Move Projekt-KIQ-HP bahn/ -> dhive/ (dhive project); add steering files
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
import React from 'react';
|
||||
import '../components/Hero.css';
|
||||
|
||||
export default function About() {
|
||||
return (
|
||||
<main>
|
||||
{/* Hero Section */}
|
||||
<section className="hero" style={{ minHeight: '50vh', paddingBottom: '40px' }}>
|
||||
<div className="hero-glow background-mesh"></div>
|
||||
<div className="app-container hero-content">
|
||||
<h1 style={{ fontSize: 'clamp(2.5rem, 6vw, 4.5rem)' }}>
|
||||
<span className="text-gradient">Über uns</span>
|
||||
</h1>
|
||||
<p className="hero-subtext" style={{ maxWidth: '800px', marginBottom: '20px', fontSize: '1.2rem' }}>
|
||||
Unsere Werte sind Nachhaltigkeit und Fortschritt. Das haben wir auch in unser Motto aufgenommen: <strong style={{color: '#fff'}}>wir hassen Verschwendung und lieben Wandel.</strong>
|
||||
</p>
|
||||
<p style={{ color: 'var(--text-secondary)', maxWidth: '800px', margin: '0 auto', lineHeight: '1.8', fontSize: '1.1rem' }}>
|
||||
Gemeinsam mit euch machen wir eure Produkte smarter. Das heißt konkret: Wir erarbeiten mit euch ein Konzept, um euer Produkt mit der passenden Sensorik, Datenerfassung und zugehöriger Software auszustatten, damit euer Produkt bestimmte Fragestellungen in Zukunft selbstständig beantworten kann.
|
||||
<br/><br/>
|
||||
Die anschließende Automatisierung oder die Betreuung bei der Integration in die Herstellung von Produktserien gehört dabei dazu.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Stats Section */}
|
||||
<section className="app-container" style={{ padding: '20px 20px 60px 20px', textAlign: 'center' }}>
|
||||
<h2 style={{ fontSize: '1.5rem', marginBottom: '30px', color: '#fff' }}>Zahlen, Daten, Fakten</h2>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', gap: '40px', flexWrap: 'wrap' }}>
|
||||
<div className="glass-panel" style={{ padding: '30px 50px', borderRadius: '16px', minWidth: '200px' }}>
|
||||
<h3 style={{ fontSize: '3rem', color: 'var(--accent-color)', marginBottom: '5px' }}>2021</h3>
|
||||
<p style={{ color: 'var(--text-secondary)', fontWeight: '500' }}>Gründung</p>
|
||||
</div>
|
||||
<div className="glass-panel" style={{ padding: '30px 50px', borderRadius: '16px', minWidth: '200px' }}>
|
||||
<h3 style={{ fontSize: '3rem', color: 'var(--accent-color)', marginBottom: '5px' }}>50+</h3>
|
||||
<p style={{ color: 'var(--text-secondary)', fontWeight: '500' }}>Projekte erfolgreich umgesetzt</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Team Intro */}
|
||||
<section className="app-container" style={{ padding: '40px 20px 100px 20px' }}>
|
||||
<div className="glass-panel" style={{ padding: '60px', borderRadius: '24px', border: '1px solid rgba(0, 255, 0, 0.1)' }}>
|
||||
<h2 style={{ fontSize: '2rem', marginBottom: '20px', color: '#fff' }}>Das sind wir</h2>
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.8', marginBottom: '30px', fontSize: '1.05rem', maxWidth: '800px' }}>
|
||||
Unser Team setzt sich zusammen aus Problemlösern mit wissenschaftlichen Hintergründen in den Bereichen der Regelungs- und Elektrotechnik, Mechatronik, Maschinenbau, Informatik und Physik. Und wir alle haben uns in irgendeiner Form dem Generieren von Wissen durch das Erheben und Verarbeiten von Daten verschrieben.
|
||||
<br/><br/>
|
||||
Stellvertretend für unser Team stellen wir hier unsere Gründer vor: André – unser KI, Leadership und Sensorik-Experte – und Alex – unser Mess-, Regelungs und Automatisierungs-Experte. Die beiden begleiten unsere Kunden und unsere internen und externen Mitarbeitenden durch die Projekte.
|
||||
</p>
|
||||
|
||||
{/* Founders Grid */}
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(340px, 1fr))', gap: '40px', marginTop: '60px' }}>
|
||||
|
||||
{/* André */}
|
||||
<div style={{ background: 'rgba(255,255,255,0.02)', padding: '40px', borderRadius: '20px', border: '1px solid rgba(255,255,255,0.05)' }}>
|
||||
<h3 style={{ fontSize: '1.8rem', color: '#fff', marginBottom: '5px' }}>Dr. André Knie</h3>
|
||||
<p style={{ color: 'var(--accent-color)', fontWeight: '600', marginBottom: '25px', fontSize: '1.1rem' }}>Mensch-Maschine-Moderator</p>
|
||||
|
||||
<div style={{ fontStyle: 'italic', color: '#ccc', borderLeft: '3px solid var(--accent-color)', paddingLeft: '15px', marginBottom: '20px', lineHeight: '1.7' }}>
|
||||
„Die Angst vor Technologie und Veränderung lähmt viele Organisationen und Menschen. Ich helfe dabei, diese Ängste zu überwinden, und gestalte Technologie sowie Change-Prozesse so, dass sie echten Mehrwert schaffen und Begeisterung auslösen."
|
||||
</div>
|
||||
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', marginBottom: '15px' }}>
|
||||
Als promovierter Physiker betrachte ich Systeme und Zusammenhänge aus einer einzigartigen Perspektive. Meine wissenschaftliche Herangehensweise ermöglicht es mir, komplexe Herausforderungen analytisch zu durchdringen und visionäre Lösungen zu entwickeln, die technisch fundiert und praxisnah sind.
|
||||
</p>
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', marginBottom: '15px' }}>
|
||||
Doch Technik allein reicht nicht aus. Ich verbinde diese Visionen mit Menschlichkeit und einer Kultur, die Veränderung als Chance begreift. Ein Beispiel für meine gelebten Werte ist mein Verzicht auf Gehalt, um im Jobsharing die Möglichkeit zu haben, Führung auf Augenhöhe zu übernehmen und das Team weiterzuentwickeln. Diese menschenzentrierte Haltung ist das Herzstück meiner Arbeit.
|
||||
</p>
|
||||
|
||||
<div style={{ background: 'rgba(0,255,0,0.03)', padding: '15px 20px', borderRadius: '12px', marginBottom: '20px' }}>
|
||||
<p style={{ color: '#fff', marginBottom: '10px', fontWeight: '500' }}>Meine Expertise konzentriert sich auf drei Kernthemen:</p>
|
||||
<ol style={{ color: 'var(--text-secondary)', marginLeft: '20px', lineHeight: '1.6' }}>
|
||||
<li>Innovation und Technologie</li>
|
||||
<li>Mensch & Kultur</li>
|
||||
<li>Verantwortung</li>
|
||||
</ol>
|
||||
<p style={{ color: 'var(--text-secondary)', marginTop: '10px', fontSize: '0.95rem' }}>Diese Säulen bilden das Fundament meiner Beratung, Workshops und Vorträge.</p>
|
||||
</div>
|
||||
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', fontSize: '0.95rem' }}>
|
||||
In Projekten sind KI, Sensorik, Konzeption, Produktentwicklung, Projektplanung, Design Thinking, New Work und Projektdurchführung Andrés Hauptarbeitsbereiche. Er stellt gerne unbequeme Warum-Fragen und hat stets den Kunden unserer Kunden im Blick. Wenn das Ziel klar ist, wird an Konzept und Umsetzung gearbeitet. Meistens ist André aber dabei das Ziel gemeinsam mit dem Kunden zu schärfen und das Problem zu analysieren.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Alex */}
|
||||
<div style={{ background: 'rgba(255,255,255,0.02)', padding: '40px', borderRadius: '20px', border: '1px solid rgba(255,255,255,0.05)' }}>
|
||||
<h3 style={{ fontSize: '1.8rem', color: '#fff', marginBottom: '5px' }}>Dr.-Ing. Alexander Schrodt</h3>
|
||||
<p style={{ color: 'var(--accent-color)', fontWeight: '600', marginBottom: '25px', fontSize: '1.1rem' }}>Automatisierungs-Analyse-Architekt</p>
|
||||
|
||||
<div style={{ fontStyle: 'italic', color: '#ccc', borderLeft: '3px solid var(--accent-color)', paddingLeft: '15px', marginBottom: '20px', lineHeight: '1.7' }}>
|
||||
„Ich führe die KI-Diskussion über Buzzwords hinaus: Für mich ist KI keine universelle Antwort, sondern ein hochspezialisiertes Werkzeug, um in technischen Systemen echten, messbaren Mehrwert zu schaffen."
|
||||
</div>
|
||||
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', marginBottom: '15px' }}>
|
||||
Mein Fundament als promovierter Regelungstechniker ist die Systemtheorie. Ich verstehe, wie technische Prozesse im Kern funktionieren, wie sie stabil designt und sicher betrieben werden. Diese systemische Sicht erlaubt es mir, nicht nur KI-Modelle zu trainieren, sondern sie so in die Automatisierung zu integrieren, dass sie robust, effizient und vorhersagbar arbeiten.
|
||||
</p>
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', marginBottom: '20px' }}>
|
||||
Ich suche nicht nach dem neuesten Algorithmus, sondern nach der optimalen und einfachsten Lösung, die das Problem des Kunden nachhaltig löst.
|
||||
</p>
|
||||
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', marginBottom: '20px' }}>
|
||||
Im Maschinenbau und in der Produktion führt dieser Ansatz zu messbaren Erfolgen: Wir senken den Ausschuss, minimieren Ausfallzeiten und vereinfachen die Wartung. Wir nutzen KI nicht um ihrer selbst willen, sondern um die Effizienz zu steigern und eine präzise, datenbasierte Einsicht in die gesamten Abläufe zu gewinnen.
|
||||
</p>
|
||||
|
||||
<div style={{ fontStyle: 'italic', color: '#ccc', borderLeft: '3px solid var(--accent-color)', paddingLeft: '15px', marginBottom: '20px', lineHeight: '1.7' }}>
|
||||
„Meine Leidenschaft ist es, komplexe Systeme zu entschlüsseln und sie robuster und leistungsfähiger zu machen. Ich befähige unsere Kunden und Teams, Daten nicht nur zu sammeln, sondern sie für stabile, effiziente Prozesse zu nutzen und Wissen in einen klaren Wettbewerbsvorteil zu verwandeln.“
|
||||
</div>
|
||||
|
||||
<p style={{ color: 'var(--text-secondary)', lineHeight: '1.7', fontSize: '0.95rem' }}>
|
||||
In Projekten liegen Alex‘ Schwerpunkte in der Systemtheorie, der regelungsorientierten Datenanalyse (KI und klassisch) und der Konzeption smarter Automatisierungslösungen. Er ist der Architekt, der sicherstellt, dass die von dHive entwickelten Lösungen nicht nur intelligent, sondern auch industrietauglich sind.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
.ar-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.ar-hero {
|
||||
position: relative;
|
||||
padding: 160px 20px 80px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ar-hero-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ar-hero h1 {
|
||||
font-size: clamp(2.5rem, 5vw, 3.5rem);
|
||||
line-height: 1.1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ar-label-tag {
|
||||
display: inline-block;
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
border: 1px solid rgba(0, 255, 0, 0.3);
|
||||
color: var(--accent-color);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
padding: 6px 16px;
|
||||
border-radius: 50px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.ar-subtitle {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.ar-login-alt {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.ar-login-link {
|
||||
color: var(--accent-color);
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* Form */
|
||||
.ar-container {
|
||||
max-width: 820px !important;
|
||||
}
|
||||
|
||||
.ar-form {
|
||||
padding: 48px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.ar-form-header {
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
|
||||
.ar-form-header h2 {
|
||||
font-size: 1.6rem;
|
||||
color: #fff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ar-form-header p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.ar-grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.ar-grid-2 { grid-template-columns: 1fr; }
|
||||
.ar-form { padding: 28px 20px; }
|
||||
}
|
||||
|
||||
.ar-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ar-label {
|
||||
font-size: 0.88rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.ar-required {
|
||||
color: var(--accent-color);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.ar-input {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
color: var(--text-primary);
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 1rem;
|
||||
padding: 13px 16px;
|
||||
transition: border-color 0.25s, box-shadow 0.25s;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.ar-input option {
|
||||
background: #1a1a1a;
|
||||
}
|
||||
|
||||
.ar-input:focus {
|
||||
border-color: rgba(0, 255, 0, 0.5);
|
||||
box-shadow: 0 0 0 3px rgba(0, 255, 0, 0.08);
|
||||
}
|
||||
|
||||
.ar-textarea {
|
||||
resize: vertical;
|
||||
min-height: 130px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ar-disclaimer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
background: rgba(255,255,255,0.02);
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
border-radius: 10px;
|
||||
padding: 14px 16px;
|
||||
margin: 24px 0;
|
||||
}
|
||||
|
||||
.ar-disclaimer svg {
|
||||
flex-shrink: 0;
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.ar-submit-btn {
|
||||
width: 100%;
|
||||
font-size: 1.05rem;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
.ar-success {
|
||||
max-width: 500px;
|
||||
margin: 200px auto 0;
|
||||
padding: 60px 48px;
|
||||
text-align: center;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
.ar-success-icon {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 255, 0, 0.12);
|
||||
border: 2px solid rgba(0, 255, 0, 0.4);
|
||||
color: var(--accent-color);
|
||||
font-size: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 0 auto 24px;
|
||||
}
|
||||
|
||||
.ar-success h2 {
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ar-success p {
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.ar-redirect {
|
||||
font-size: 0.85rem;
|
||||
color: rgba(153,153,153,0.6) !important;
|
||||
margin-top: 24px !important;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate, Link } from 'react-router-dom';
|
||||
import './AccessRequest.css';
|
||||
|
||||
const API_BASE = import.meta.env.VITE_API_URL || '';
|
||||
|
||||
const FIELD = ({ id, label, type = 'text', required = true, value, onChange, as: As = 'input', children, rows }) => (
|
||||
<div className="ar-field">
|
||||
<label className="ar-label" htmlFor={id}>{label}{required && <span className="ar-required">*</span>}</label>
|
||||
{As === 'select' ? (
|
||||
<select id={id} className="ar-input" value={value} onChange={onChange} required={required}>
|
||||
{children}
|
||||
</select>
|
||||
) : As === 'textarea' ? (
|
||||
<textarea id={id} className="ar-input ar-textarea" value={value} onChange={onChange} required={required} rows={rows || 4} />
|
||||
) : (
|
||||
<input id={id} type={type} className="ar-input" value={value} onChange={onChange} required={required} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
export default function AccessRequest() {
|
||||
const [formData, setFormData] = useState({
|
||||
name: '', company: '', role: '', email: '', phone: '', reason: '', purpose: ''
|
||||
});
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [error, setError] = useState('');
|
||||
const navigate = useNavigate();
|
||||
|
||||
const set = (key) => (e) => setFormData(prev => ({ ...prev, [key]: e.target.value }));
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
setSubmitting(true);
|
||||
setError('');
|
||||
try {
|
||||
if (!formData.name || !formData.email || !formData.company) {
|
||||
throw new Error('Pflichtfelder fehlen.');
|
||||
}
|
||||
|
||||
const res = await fetch(`${API_BASE}/api/access-requests`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ user_data: formData }),
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
setSubmitted(true);
|
||||
setTimeout(() => navigate('/'), 4000);
|
||||
} else {
|
||||
setError('Übermittlung fehlgeschlagen. Bitte versuchen Sie es erneut.');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setError('Fehler bei der Übermittlung. Bitte prüfen Sie Ihre Eingaben.');
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (submitted) {
|
||||
return (
|
||||
<div className="ar-page">
|
||||
<div className="ar-success glass-panel">
|
||||
<div className="ar-success-icon">✓</div>
|
||||
<h2>Anfrage eingegangen</h2>
|
||||
<p>Vielen Dank, <strong>{formData.name}</strong>. Wir prüfen Ihre Anfrage und melden uns in Kürze bei <strong>{formData.email}</strong>.</p>
|
||||
<p className="ar-redirect">Sie werden automatisch weitergeleitet…</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="ar-page">
|
||||
{/* Hero */}
|
||||
<div className="ar-hero">
|
||||
<div className="hero-glow background-mesh" />
|
||||
<div className="ar-hero-content">
|
||||
<p className="ar-label-tag">Geschützter Bereich</p>
|
||||
<h1>Zugang <span className="text-gradient">anfragen</span></h1>
|
||||
<p className="ar-subtitle">Bitte geben Sie Ihre beruflichen Daten an. Unser Team prüft Ihre Anfrage und schaltet Ihnen den Zugang zu vertraulichen Investorenunterlagen frei.</p>
|
||||
<div className="ar-login-alt">
|
||||
Bereits registriert? <Link to="/login" className="ar-login-link">Hier einloggen</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Form */}
|
||||
<div className="ar-container app-container">
|
||||
<form className="ar-form glass-panel" onSubmit={handleSubmit} noValidate>
|
||||
<div className="ar-form-header">
|
||||
<h2>Ihre Daten</h2>
|
||||
<p>Alle mit <span className="ar-required">*</span> markierten Felder sind Pflichtfelder.</p>
|
||||
</div>
|
||||
|
||||
<div className="ar-grid-2">
|
||||
<FIELD id="ar-name" label="Vollständiger Name" value={formData.name} onChange={set('name')} />
|
||||
<FIELD id="ar-company" label="Unternehmen / Organisation" value={formData.company} onChange={set('company')} />
|
||||
<FIELD id="ar-role" label="Rolle / Position" value={formData.role} onChange={set('role')} />
|
||||
<FIELD id="ar-email" label="Geschäftliche E-Mail" type="email" value={formData.email} onChange={set('email')} />
|
||||
<FIELD id="ar-phone" label="Telefonnummer" type="tel" value={formData.phone} onChange={set('phone')} />
|
||||
<FIELD id="ar-purpose" label="Gesprächsziel" as="select" value={formData.purpose} onChange={set('purpose')}>
|
||||
<option value="">Bitte wählen…</option>
|
||||
<option value="funding">Finanzierungsgespräch (MBG / Förderung)</option>
|
||||
<option value="partnership">Unternehmenspartnerschaft</option>
|
||||
<option value="evaluation">Allgemeine Evaluierung</option>
|
||||
<option value="other">Sonstiges</option>
|
||||
</FIELD>
|
||||
</div>
|
||||
|
||||
<FIELD id="ar-reason" label="Motivation & Interesse" as="textarea" rows={5} value={formData.reason} onChange={set('reason')}>
|
||||
</FIELD>
|
||||
|
||||
{error && (
|
||||
<div className="login-error" style={{ marginBottom: '16px' }}>{error}</div>
|
||||
)}
|
||||
|
||||
<div className="ar-disclaimer">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
|
||||
Ihre Daten werden vertraulich behandelt und ausschließlich zur Prüfung Ihrer Zugriffsanfrage verwendet.
|
||||
</div>
|
||||
|
||||
<button type="submit" className="primary-button ar-submit-btn" disabled={submitting}>
|
||||
{submitting ? 'Wird gesendet…' : 'Zugang anfragen →'}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
.ad-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.ad-hero {
|
||||
position: relative;
|
||||
padding: 160px 20px 80px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ad-hero-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ad-tag {
|
||||
display: inline-block;
|
||||
background: rgba(255, 165, 0, 0.1);
|
||||
border: 1px solid rgba(255, 165, 0, 0.3);
|
||||
color: #ffb347;
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
padding: 6px 16px;
|
||||
border-radius: 50px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.ad-hero h1 {
|
||||
font-size: clamp(2.5rem, 5vw, 3.5rem);
|
||||
line-height: 1.1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ad-subtitle {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.ad-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
max-width: 1100px !important;
|
||||
}
|
||||
|
||||
/* Metrics */
|
||||
.ad-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.ad-metrics { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
.ad-metric {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 24px 16px;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.ad-metric-highlight {
|
||||
border-color: rgba(255, 165, 0, 0.3) !important;
|
||||
background: rgba(255, 165, 0, 0.05) !important;
|
||||
}
|
||||
|
||||
.ad-metric-icon { font-size: 1.4rem; }
|
||||
|
||||
.ad-metric-val {
|
||||
font-size: 2.2rem;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ad-metric-label {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
/* Table section */
|
||||
.ad-section {
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ad-section-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 28px 32px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.ad-section-head h2 {
|
||||
font-size: 1.3rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.ad-count {
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-secondary);
|
||||
background: rgba(255,255,255,0.04);
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
border: 1px solid rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.ad-table-wrap {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.ad-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.ad-table th {
|
||||
text-align: left;
|
||||
padding: 14px 20px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.07em;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.ad-row {
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.ad-row:hover, .ad-row-active {
|
||||
background: rgba(255,255,255,0.03);
|
||||
}
|
||||
|
||||
.ad-row td {
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||
vertical-align: middle;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.ad-row td strong {
|
||||
display: block;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.ad-sub {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.ad-muted { color: var(--text-secondary); }
|
||||
|
||||
.ad-done { display: block; text-align: center; }
|
||||
|
||||
/* Badges */
|
||||
.ad-badge {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.ad-badge-pending { background: rgba(255,165,0,0.15); color: #ffb347; border: 1px solid rgba(255,165,0,0.3); }
|
||||
.ad-badge-approved { background: rgba(0,255,0,0.1); color: var(--accent-color); border: 1px solid rgba(0,255,0,0.25); }
|
||||
.ad-badge-rejected { background: rgba(255,60,60,0.1); color: #ff6b6b; border: 1px solid rgba(255,60,60,0.2); }
|
||||
|
||||
/* Action buttons */
|
||||
.ad-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ad-btn {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
padding: 6px 14px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.ad-btn:hover { opacity: 0.8; }
|
||||
.ad-btn-approve { background: rgba(0,255,0,0.2); color: var(--accent-color); border: 1px solid rgba(0,255,0,0.3); }
|
||||
.ad-btn-reject { background: rgba(255,60,60,0.15); color: #ff6b6b; border: 1px solid rgba(255,60,60,0.25); }
|
||||
|
||||
/* Detail row */
|
||||
.ad-detail-row td {
|
||||
background: rgba(0,255,0,0.02);
|
||||
border-bottom: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.ad-detail {
|
||||
padding: 16px 20px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.ad-detail a { color: var(--accent-color); }
|
||||
|
||||
.ad-detail-reason {
|
||||
margin: 8px 0 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Info grid */
|
||||
.ad-info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.ad-info-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
.ad-info {
|
||||
border-radius: 16px;
|
||||
padding: 28px;
|
||||
}
|
||||
|
||||
.ad-info h3 {
|
||||
font-size: 1.05rem;
|
||||
color: #fff;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ad-info-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.ad-info-list li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 0.88rem;
|
||||
color: var(--text-secondary);
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.ad-info-list li:last-child { border-bottom: none; padding-bottom: 0; }
|
||||
|
||||
.ad-info-list strong {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Note */
|
||||
.ad-mockup-note {
|
||||
text-align: center;
|
||||
font-size: 0.82rem;
|
||||
color: rgba(153,153,153,0.5);
|
||||
margin-top: 8px;
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import './AdminDashboard.css';
|
||||
|
||||
const API_BASE = import.meta.env.VITE_API_URL || '';
|
||||
|
||||
const STATUS_LABELS = {
|
||||
pending: { label: 'Ausstehend', cls: 'ad-badge-pending' },
|
||||
approved: { label: 'Genehmigt', cls: 'ad-badge-approved' },
|
||||
rejected: { label: 'Abgelehnt', cls: 'ad-badge-rejected' },
|
||||
};
|
||||
|
||||
export default function AdminDashboard() {
|
||||
const navigate = useNavigate();
|
||||
const { logout } = useAuth();
|
||||
const [requests, setRequests] = useState([]);
|
||||
const [activeRow, setActiveRow] = useState(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
fetchRequests();
|
||||
}, []);
|
||||
|
||||
const fetchRequests = async () => {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/api/access-requests`, {
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!res.ok) throw new Error('Fetch failed');
|
||||
const data = await res.json();
|
||||
|
||||
const formatted = data.map(row => ({
|
||||
id: row.id,
|
||||
status: row.status,
|
||||
date: new Date(row.created_at).toLocaleDateString('de-DE'),
|
||||
name: row.user_data?.name || 'Unbekannt',
|
||||
company: row.user_data?.company || 'Unbekannt',
|
||||
role: row.user_data?.role || '',
|
||||
email: row.user_data?.email || '',
|
||||
purpose: row.user_data?.purpose || '',
|
||||
reason: row.user_data?.reason || ''
|
||||
}));
|
||||
|
||||
setRequests(formatted);
|
||||
} catch (err) {
|
||||
console.error('Error fetching requests:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const updateStatus = async (id, newStatus) => {
|
||||
try {
|
||||
const res = await fetch(`${API_BASE}/api/access-requests/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify({ status: newStatus }),
|
||||
});
|
||||
if (!res.ok) throw new Error('Update failed');
|
||||
|
||||
setRequests(rs => rs.map(r => r.id === id ? { ...r, status: newStatus } : r));
|
||||
} catch (err) {
|
||||
console.error('Error updating status:', err);
|
||||
alert('Status-Update fehlgeschlagen.');
|
||||
}
|
||||
};
|
||||
|
||||
const approve = (id) => updateStatus(id, 'approved');
|
||||
const reject = (id) => updateStatus(id, 'rejected');
|
||||
|
||||
const metrics = {
|
||||
total: requests.length,
|
||||
pending: requests.filter(r => r.status === 'pending').length,
|
||||
approved: requests.filter(r => r.status === 'approved').length,
|
||||
rejected: requests.filter(r => r.status === 'rejected').length,
|
||||
};
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
navigate('/');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ad-page">
|
||||
<div className="ad-hero">
|
||||
<div className="hero-glow background-mesh" />
|
||||
<div className="ad-hero-content">
|
||||
<div className="admin-header-row">
|
||||
<p className="ad-tag">Control Center</p>
|
||||
<button onClick={handleLogout} className="logout-btn">Abmelden</button>
|
||||
</div>
|
||||
<h1>Admin <span className="text-gradient">Dashboard</span></h1>
|
||||
<p className="ad-subtitle">Verwaltung von Zugriffsanfragen und Systemmetriken.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="ad-container app-container">
|
||||
|
||||
{/* Metrics */}
|
||||
<div className="ad-metrics">
|
||||
{[
|
||||
{ label: 'Gesamt Anfragen', val: metrics.total, icon: '📋' },
|
||||
{ label: 'Ausstehend', val: metrics.pending, icon: '⏳', highlight: true },
|
||||
{ label: 'Genehmigt', val: metrics.approved, icon: '✅' },
|
||||
{ label: 'Abgelehnt', val: metrics.rejected, icon: '❌' },
|
||||
].map(({ label, val, icon, highlight }) => (
|
||||
<div key={label} className={`ad-metric glass-panel ${highlight && val > 0 ? 'ad-metric-highlight' : ''}`}>
|
||||
<span className="ad-metric-icon">{icon}</span>
|
||||
<span className="ad-metric-val">{val}</span>
|
||||
<span className="ad-metric-label">{label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Request Table */}
|
||||
<section className="ad-section glass-panel">
|
||||
<div className="ad-section-head">
|
||||
<h2>Zugriffsanfragen</h2>
|
||||
<span className="ad-count">{requests.length} Einträge</span>
|
||||
</div>
|
||||
<div className="ad-table-wrap">
|
||||
<table className="ad-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name & Organisation</th>
|
||||
<th>Rolle</th>
|
||||
<th>Gesprächsziel</th>
|
||||
<th>Datum</th>
|
||||
<th>Status</th>
|
||||
<th>Aktionen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{requests.map(r => {
|
||||
const { label, cls } = STATUS_LABELS[r.status];
|
||||
return (
|
||||
<React.Fragment key={r.id}>
|
||||
<tr
|
||||
className={`ad-row ${activeRow === r.id ? 'ad-row-active' : ''}`}
|
||||
onClick={() => setActiveRow(activeRow === r.id ? null : r.id)}
|
||||
>
|
||||
<td>
|
||||
<strong>{r.name}</strong>
|
||||
<span className="ad-sub">{r.company}</span>
|
||||
</td>
|
||||
<td className="ad-muted">{r.role}</td>
|
||||
<td className="ad-muted">{r.purpose}</td>
|
||||
<td className="ad-muted">{r.date}</td>
|
||||
<td><span className={`ad-badge ${cls}`}>{label}</span></td>
|
||||
<td>
|
||||
{r.status === 'pending' && (
|
||||
<div className="ad-actions" onClick={e => e.stopPropagation()}>
|
||||
<button className="ad-btn ad-btn-approve" onClick={() => approve(r.id)}>Genehmigen</button>
|
||||
<button className="ad-btn ad-btn-reject" onClick={() => reject(r.id)}>Ablehnen</button>
|
||||
</div>
|
||||
)}
|
||||
{r.status !== 'pending' && (
|
||||
<span className="ad-muted ad-done">–</span>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
{activeRow === r.id && (
|
||||
<tr className="ad-detail-row">
|
||||
<td colSpan={6}>
|
||||
<div className="ad-detail">
|
||||
<strong>E-Mail:</strong> <a href={`mailto:${r.email}`}>{r.email}</a>
|
||||
<br /><br />
|
||||
<strong>Kommentar / Motivation:</strong>
|
||||
<p className="ad-detail-reason">{r.reason}</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* System info */}
|
||||
<section className="ad-info-grid">
|
||||
<div className="ad-info glass-panel">
|
||||
<h3>Systemstatus</h3>
|
||||
<ul className="ad-info-list">
|
||||
<li><span>Genehmigte Nutzer</span><strong>{metrics.approved}</strong></li>
|
||||
<li><span>Ausstehende Anfragen</span><strong>{metrics.pending}</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="ad-info glass-panel">
|
||||
<h3>Hinweise</h3>
|
||||
<ul className="ad-info-list">
|
||||
<li><span>✉ E-Mail-Benachrichtigung</span><strong>Aktiv</strong></li>
|
||||
<li><span>📄 Pitch Deck</span><strong>Versand per E-Mail</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{loading && <p style={{textAlign: 'center', marginTop: '2rem'}}>Lade Anfragen...</p>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
import React from 'react';
|
||||
import '../components/Hero.css';
|
||||
|
||||
export default function Datenschutz() {
|
||||
return (
|
||||
<main>
|
||||
<section className="app-container" style={{ paddingTop: '150px', paddingBottom: '100px', maxWidth: '900px', margin: '0 auto' }}>
|
||||
<h1 style={{ fontSize: '3rem', marginBottom: '40px' }}><span className="text-gradient">Datenschutzerklärung</span></h1>
|
||||
|
||||
<div className="legal-text-container" style={{ color: 'var(--text-secondary)', lineHeight: '1.8', fontSize: '1.05rem' }}>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '30px', marginTop: '50px' }}>I. Allgemeine Informationen zum Datenschutz & Betroffenenrechte</h2>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§1 Allgemeine Informationen</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Datenschutz ist ein wichtiges Thema. Im Folgenden informieren wir über die Erhebung und Verarbeitung von personenbezogenen Daten. Personenbezogene Daten sind alle Daten, die auf Sie persönlich beziehbar sind.
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
<strong>Verantwortlicher gem. Art. 4 Abs. 7 DSGVO</strong><br/>
|
||||
Data Hive Cassel GmbH<br/>
|
||||
Universitätsplatz 12<br/>
|
||||
34127 Kassel
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
<strong>Datenschutzbeauftragter</strong><br/>
|
||||
Den persönlich bestellten Datenschutzbeauftragten unserer Firma erreichen Sie unter folgender Adresse:<br/>
|
||||
Herr Dr.-Ing. Alexander Schrodt<br/>
|
||||
Data Hive Cassel GmbH<br/>
|
||||
Universitätsplatz 12<br/>
|
||||
34127 Kassel<br/>
|
||||
E-Mail: schrodt@d-hive.de
|
||||
</p>
|
||||
<p style={{ marginBottom: '30px' }}>Sollten Sie Fragen zur Verarbeitung, der Sicherheit oder ein Auskunftsverlangen haben, können Sie sich direkt vertrauensvoll an diesen wenden.</p>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§2 Allgemeine Übersicht der Daten und Verarbeitungsvorgänge</h3>
|
||||
<p style={{ marginBottom: '20px' }}>Wir wollen Ihnen die geforderte Übersichtlichkeit gem. Art. 12 DSGVO bieten. Daher folgende Übersicht der Verarbeitungen:</p>
|
||||
|
||||
<p style={{ marginBottom: '10px' }}><strong>Arten der verarbeiteten Daten:</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '20px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Nutzungsdaten Kommunikationsdaten (Beim Abruf einer Internetseite, IP Adresse, Geräteinformation, Zugriffszeit und Zugriffszeitpunkt usw.)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Kontaktdaten bei Anmeldung oder Eingabe der Daten</li>
|
||||
<li style={{ marginBottom: '8px' }}>Bestandsdaten (Name, Firma, Adresse)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Kommunikationsdaten (ggf. Meta-Daten über Anrufe, E-Mails)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Inhaltsdaten (insbesondere bei der Zusendung von Mails)</li>
|
||||
</ul>
|
||||
|
||||
<p style={{ marginBottom: '20px' }}>Ausserdem (intern) noch folgende zusätzliche Daten für unsere Kunden, Interessenten, Lieferanten und Geschäftspartnern für die Erbringung von Leistungen im Bereich Angebots- und Vertragswesen, Service und Marketing, der Direktwerbung und der Kundenpflege:</p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '20px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Vertragsdaten</li>
|
||||
<li style={{ marginBottom: '8px' }}>Bestandsdaten der Kunden (CRM)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Lieferantendaten</li>
|
||||
<li style={{ marginBottom: '8px' }}>Zahlungsdaten</li>
|
||||
<li style={{ marginBottom: '8px' }}>Auftragsdaten und Rechnungsdaten</li>
|
||||
</ul>
|
||||
|
||||
<p style={{ marginBottom: '10px' }}><strong>Betroffene Personen (Kategorien):</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '20px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Nutzer dieser Internetseite (auch Besucher genannt)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Kunden</li>
|
||||
<li style={{ marginBottom: '8px' }}>Lieferanten</li>
|
||||
</ul>
|
||||
|
||||
<p style={{ marginBottom: '10px' }}><strong>Zwecke:</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '30px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Betreiben der Website und Zur Verfügung stellen der Information</li>
|
||||
<li style={{ marginBottom: '8px' }}>Die Sicherstellung des Betriebs der Internetseite und unserer Systeme (z. B. Firewall)</li>
|
||||
<li style={{ marginBottom: '8px' }}>Kommunikation mit unseren Kunden</li>
|
||||
<li style={{ marginBottom: '8px' }}>Beantwortung von Anfragen</li>
|
||||
<li style={{ marginBottom: '8px' }}>Optimierung und Analyse der Website</li>
|
||||
<li style={{ marginBottom: '8px' }}>Zur Verfügung stellen von Informationen für unsere (potentiellen) Kunden</li>
|
||||
</ul>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§3 Ihre Rechte</h3>
|
||||
<p style={{ marginBottom: '15px' }}>Sie haben gegenüber uns folgende Rechte hinsichtlich der Sie betreffenden personenbezogenen Daten:</p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '20px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Recht auf Auskunft, Berichtigung oder Löschung, Einschränkung der Verarbeitung, Widerspruch gegen die Verarbeitung, Datenübertragbarkeit, Beschwerde bei der Datenschutz-Aufsichtsbehörde.</li>
|
||||
</ul>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Ausführliche Rechte:</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '20px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 15 DSGVO Auskunft über Ihre von uns verarbeiteten personenbezogenen Daten zu verlangen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 16 DSGVO unverzüglich die Berichtigung unrichtiger oder Vervollständigung Ihrer Daten zu verlangen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 17 DSGVO die Löschung Ihrer Daten zu verlangen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 18 DSGVO die Einschränkung der Verarbeitung zu verlangen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 20 DSGVO Ihre Daten in strukturiertem Format zu erhalten (Datenübertragbarkeit).</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 7 Abs. 3 DSGVO Ihre einmal erteilte Einwilligung jederzeit zu widerrufen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>gemäß Art. 77 DSGVO sich bei einer Aufsichtsbehörde zu beschweren.</li>
|
||||
</ul>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Ausnahmen (Kein Recht auf Löschung):</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '30px' }}>
|
||||
<li style={{ marginBottom: '8px' }}>Zur Ausübung des Rechts auf freie Meinungsäußerung und Information.</li>
|
||||
<li style={{ marginBottom: '8px' }}>Zur Erfüllung rechtlicher Verpflichtungen.</li>
|
||||
<li style={{ marginBottom: '8px' }}>Aus Gründen des öffentlichen Interesses (Gesundheit, Archiv, Forschung).</li>
|
||||
<li style={{ marginBottom: '8px' }}>Zur Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen.</li>
|
||||
</ul>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§4 Rechtsgrundlagen allgemein</h3>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Bei der Verarbeitung zur Erfüllung eines Vertrags dient Art. 6 Abs. 1 lit. b DSGVO als Rechtsgrundlage. Zur Wahrung eines berechtigten Interesses dient Art. 6 Abs. 1 lit. f DSGVO. Zur Erfüllung rechtlicher Verpflichtungen dient Art. 6 Abs. 1 lit. c DSGVO. Bei lebenswichtigen Interessen dient Art. 6 Abs. 1 lit. d DSGVO. Bei Einwilligung dient Art. 6 Abs. 1 lit. a DSGVO.
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '30px', marginTop: '50px' }}>II. Website</h2>
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§5 Bestimmungen für Nutzer der Website</h3>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Allgemeine Daten und Logfiles</strong></p>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Bei informatorischer Nutzung erheben wir personenlose Daten, die Ihr Browser übermittelt (berechtigtes Interesse, Art. 6 Abs. 1 lit. f DSGVO). Die Speicherung in Logfiles erfolgt für Sicherheit und Optimierung für maximal 7 Tage, danach werden IP-Adressen verfremdet/gelöscht.
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Cookies</strong></p>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Wir verwenden technisch notwendige Cookies (Art. 6 Abs. 1 lit. f DSGVO), die meist nach Browser-Schließung gelöscht werden, sowie Analyse-/Marketing-Cookies (Art. 6 Abs. 1 lit. a DSGVO). Sie können Cookies jederzeit im Browser löschen.
|
||||
</p>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§6 Dienste von Drittanbietern</h3>
|
||||
<p style={{ marginBottom: '20px' }}>Wir nutzen Dienste, um unser Angebot nutzerfreundlicher zu gestalten (Art. 6 Abs. 1 lit. f DSGVO oder Art. 6 Abs. 1 lit. a DSGVO bei Einwilligung).</p>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Google-Dienste</strong></p>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Wir verwenden Google Analytics (_anonymizeIp aktiviert), Google Ads (Remarketing, Conversion-Tracking) und Google Tag Manager nach Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Datenübermittlung in die USA basiert auf Art. 49 Abs. 1 lit. a DSGVO. Widerspruch möglich via Browser-Plug-In oder Cookie-Opt-Out.
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '15px' }}><strong>Weitere Dienste</strong></p>
|
||||
<ul style={{ paddingLeft: '20px', marginBottom: '30px' }}>
|
||||
<li style={{ marginBottom: '8px' }}><strong>YouTube & Vimeo:</strong> Eingebunden im erweiterten Datenschutz-Modus.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>LinkedIn Analytics / Ads:</strong> Conversion-Tracking und Retargeting.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Calendly:</strong> Zur Terminbuchung.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Social Media:</strong> Links zu den Portalen (keine Pflicht).</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Facebook-Pixel / Custom Audiences:</strong> Für Marketing.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Hotjar:</strong> Zur Nutzungsverhaltensanalyse.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Nudgify:</strong> Marketing-Hinweise.</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Webflow (CDN):</strong> Erhöhte Ausfallsicherheit (Art. 6 Abs. 1 lit. f DSGVO).</li>
|
||||
<li style={{ marginBottom: '8px' }}><strong>Matomo:</strong> Eigenes Open-Source Analytics-Tool. IP anonymisiert.</li>
|
||||
</ul>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§7 Formulare und E-Mail Kontakt</h3>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Ihre im Formular oder per Mail gesendeten Daten (Name, E-Mail, Telefon, etc.) werden nur zur Beantwortung gespeichert (Art. 6 Abs. 1 lit. f DSGVO) und anschließend gelöscht.
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '30px', marginTop: '50px' }}>III. Newsletterabonnenten</h2>
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§8 Bestimmungen für den Newsletter</h3>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Versand nur nach ausdrücklicher Einwilligung (Art. 6 Abs. 1 lit. a DSGVO). Nutzung von Web-Beacons zur Reichweitenmessung (Art. 6 Abs. 1 lit. f DSGVO). Widerruf ist per Abmeldelink jederzeit möglich.
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '30px', marginTop: '50px' }}>IV. Bewerbungen</h2>
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.3rem', marginBottom: '15px' }}>§9 Bestimmungen für Bewerber</h3>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Verarbeitung (Stammdaten, Lebenslauf, Zeugnisse) zur Durchführung des Bewerbungsverfahrens (Art. 6 Abs. 1 lit. b DSGVO, § 26 BDSG). Bei Absage erfolgt eine Löschung nach 6 Monaten, es sei denn, es liegt eine Einwilligung für den Talentpool vor.
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '30px', marginTop: '50px' }}>V. Stand der Datenschutzerklärung</h2>
|
||||
<p style={{ marginBottom: '30px' }}>
|
||||
Die Datenschutzerklärung wird gelegentlich angepasst. Stand: Juli 2023.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import Hero from '../components/Hero';
|
||||
import Stats from '../components/Stats';
|
||||
import Services from '../components/Services';
|
||||
import Customers from '../components/Customers';
|
||||
import Memberships from '../components/Memberships';
|
||||
import Team from '../components/Team';
|
||||
import UseCasesTeaser from '../components/UseCasesTeaser';
|
||||
import PlatformUSP from '../components/PlatformUSP';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main>
|
||||
<Hero />
|
||||
<Stats />
|
||||
<PlatformUSP />
|
||||
<Services />
|
||||
<UseCasesTeaser />
|
||||
<Team />
|
||||
<Customers />
|
||||
<Memberships />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import '../components/Hero.css';
|
||||
|
||||
export default function Impressum() {
|
||||
return (
|
||||
<main>
|
||||
<section className="app-container" style={{ paddingTop: '150px', paddingBottom: '100px', maxWidth: '900px', margin: '0 auto' }}>
|
||||
<h1 style={{ fontSize: '3rem', marginBottom: '40px' }}><span className="text-gradient">Impressum</span></h1>
|
||||
|
||||
<div className="legal-text-container" style={{ color: 'var(--text-secondary)', lineHeight: '1.8', fontSize: '1.05rem' }}>
|
||||
<h2 style={{ color: '#fff', fontSize: '1.5rem', marginBottom: '15px', marginTop: '40px' }}>Angaben gemäß § 5 TMG</h2>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Data Hive Cassel GmbH<br/>
|
||||
Universitätsplatz 12<br/>
|
||||
34127 Kassel
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
<strong>Vertreten durch die Geschäftsführer:</strong><br/>
|
||||
Dr.-Ing. Alexander Schrodt, Dr. André Knie
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
<strong>Kontakt:</strong><br/>
|
||||
Telefon: +49 561 8279‑3737<br/>
|
||||
E-Mail: kontakt@d-hive.de
|
||||
</p>
|
||||
|
||||
<p style={{ marginBottom: '40px' }}>
|
||||
<strong>Registereintrag:</strong><br/>
|
||||
USt-IdNr.: DE347634609<br/>
|
||||
Registergericht der GmbH: Amtsgericht Kassel<br/>
|
||||
Registernummer der GmbH: HRB 18835
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '20px', marginTop: '50px' }}>Haftungsausschluss</h2>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Haftung für Inhalte</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Haftung für Links</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Urheberrecht</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet. Soweit die Inhalte auf dieser Seite nicht vom Betreiber erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um einen entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.
|
||||
</p>
|
||||
|
||||
<h3 style={{ color: 'var(--accent-color)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Datenschutz</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Die Nutzung unserer Webseite ist in der Regel ohne Angabe personenbezogener Daten möglich. Soweit auf unseren Seiten personenbezogene Daten (beispielsweise Name, Anschrift oder eMail-Adressen) erhoben werden, erfolgt dies, soweit möglich, stets auf freiwilliger Basis. Diese Daten werden ohne Ihre ausdrückliche Zustimmung nicht an Dritte weitergegeben.
|
||||
<br/><br/>
|
||||
Wir weisen darauf hin, dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.
|
||||
<br/><br/>
|
||||
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.
|
||||
</p>
|
||||
|
||||
<h2 style={{ color: '#fff', fontSize: '1.8rem', marginBottom: '20px', marginTop: '50px' }}>Drittanbieter</h2>
|
||||
|
||||
<h3 style={{ color: 'var(--text-primary)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Google Analytics</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Diese Website benutzt Google Analytics, einen Webanalysedienst der Google Inc. ("Google"). Google Analytics verwendet sog. "Cookies", Textdateien, die auf Ihrem Computer gespeichert werden und die eine Analyse der Benutzung der Website durch Sie ermöglicht. Die durch den Cookie erzeugten Informationen über Ihre Benutzung dieser Website (einschließlich Ihrer IP-Adresse) wird an einen Server von Google in den USA übertragen und dort gespeichert. Google wird diese Informationen benutzen, um Ihre Nutzung der Website auszuwerten, um Reports über die Websiteaktivitäten für die Websitebetreiber zusammenzustellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen zu erbringen. Auch wird Google diese Informationen gegebenenfalls an Dritte übertragen, sofern dies gesetzlich vorgeschrieben oder soweit Dritte diese Daten im Auftrag von Google verarbeiten. Google wird in keinem Fall Ihre IP-Adresse mit anderen Daten der Google in Verbindung bringen. Sie können die Installation der Cookies durch eine entsprechende Einstellung Ihrer Browser Software verhindern; wir weisen Sie jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht sämtliche Funktionen dieser Website voll umfänglich nutzen können. Durch die Nutzung dieser Website erklären Sie sich mit der Bearbeitung der über Sie erhobenen Daten durch Google in der zuvor beschriebenen Art und Weise und zu dem zuvor benannten Zweck einverstanden.
|
||||
</p>
|
||||
|
||||
<h3 style={{ color: 'var(--text-primary)', fontSize: '1.2rem', marginBottom: '10px', marginTop: '30px' }}>Google AdSense</h3>
|
||||
<p style={{ marginBottom: '20px' }}>
|
||||
Diese Website benutzt Google Adsense, einen Webanzeigendienst der Google Inc., USA ("Google"). Google Adsense verwendet sog. "Cookies" (Textdateien), die auf Ihrem Computer gespeichert werden und die eine Analyse der Benutzung der Website durch Sie ermöglicht. Google Adsense verwendet auch sog. "Web Beacons" (kleine unsichtbare Grafiken) zur Sammlung von Informationen. Durch die Verwendung des Web Beacons können einfache Aktionen wie der Besucherverkehr auf der Webseite aufgezeichnet und gesammelt werden. Die durch den Cookie und/oder Web Beacon erzeugten Informationen über Ihre Benutzung dieser Website (einschließlich Ihrer IP-Adresse) werden an einen Server von Google in den USA übertragen und dort gespeichert. Google wird diese Informationen benutzen, um Ihre Nutzung der Website im Hinblick auf die Anzeigen auszuwerten, um Reports über die Websiteaktivitäten und Anzeigen für die Websitebetreiber zusammenzustellen und um weitere mit der Websitenutzung und der Internetnutzung verbundene Dienstleistungen zu erbringen. Auch wird Google diese Informationen gegebenenfalls an Dritte übertragen, sofern dies gesetzlich vorgeschrieben oder soweit Dritte diese Daten im Auftrag von Google verarbeiten. Google wird in keinem Fall Ihre IP-Adresse mit anderen Daten der Google in Verbindung bringen. Das Speichern von Cookies auf Ihrer Festplatte und die Anzeige von Web Beacons können Sie verhindern, indem Sie in Ihren Browser-Einstellungen "keine Cookies akzeptieren" wählen (Im MS Internet-Explorer unter "Extras > Internetoptionen > Datenschutz > Einstellung"; im Firefox unter "Extras > Einstellungen > Datenschutz > Cookies"); wir weisen Sie jedoch darauf hin, dass Sie in diesem Fall gegebenenfalls nicht sämtliche Funktionen dieser Website voll umfänglich nutzen können. Durch die Nutzung dieser Website erklären Sie sich mit der Bearbeitung der über Sie erhobenen Daten durch Google in der zuvor beschriebenen Art und Weise und zu dem zuvor benannten Zweck einverstanden.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
.login-page {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.login-hero-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
max-width: 480px !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
padding: 60px 40px;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
.login-header {
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.login-tag {
|
||||
display: inline-block;
|
||||
padding: 6px 14px;
|
||||
background: rgba(var(--accent-color-rgb), 0.1);
|
||||
color: var(--accent-color);
|
||||
border-radius: 100px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.login-header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.login-header p {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.login-error {
|
||||
padding: 12px 16px;
|
||||
background: rgba(255, 0, 0, 0.1);
|
||||
border: 1px solid rgba(255, 0, 0, 0.2);
|
||||
color: #ff6b6b;
|
||||
border-radius: 12px;
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.login-field {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.login-field label {
|
||||
display: block;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.login-input {
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
padding: 14px 18px;
|
||||
border-radius: 14px;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.login-input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-color);
|
||||
background: rgba(var(--accent-color-rgb), 0.05);
|
||||
box-shadow: 0 0 20px rgba(var(--accent-color-rgb), 0.1);
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
margin-top: 20px;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import './Login.css';
|
||||
|
||||
export default function Login() {
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const { login } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const from = location.state?.from?.pathname || '/restricted';
|
||||
|
||||
const handleLogin = async (e) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setError('');
|
||||
|
||||
try {
|
||||
await login(username, password);
|
||||
navigate(from, { replace: true });
|
||||
} catch (err) {
|
||||
setError('Ungültige Anmeldedaten. Bitte prüfen Sie Benutzername und Passwort.');
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="login-page">
|
||||
<div className="login-hero-bg background-mesh" />
|
||||
|
||||
<div className="login-container app-container">
|
||||
<form className="login-form glass-panel" onSubmit={handleLogin}>
|
||||
<div className="login-header">
|
||||
<div className="login-tag">Interner Bereich</div>
|
||||
<h1>System <span className="text-gradient">Login</span></h1>
|
||||
<p>Bitte authentifizieren Sie sich, um fortzufahren.</p>
|
||||
</div>
|
||||
|
||||
{error && <div className="login-error">{error}</div>}
|
||||
|
||||
<div className="login-field">
|
||||
<label htmlFor="username">Benutzername</label>
|
||||
<input
|
||||
id="username"
|
||||
type="text"
|
||||
className="login-input"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
autoComplete="username"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="login-field">
|
||||
<label htmlFor="password">Passwort</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
className="login-input"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
autoComplete="current-password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button type="submit" className="primary-button login-btn" disabled={loading}>
|
||||
{loading ? 'Lade...' : 'Anmelden →'}
|
||||
</button>
|
||||
|
||||
<p className="login-footer">
|
||||
Probleme beim Login? Kontaktieren Sie den Systemadministrator.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
.ra-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.ra-hero {
|
||||
position: relative;
|
||||
padding: 160px 20px 80px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ra-hero-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.ra-badge {
|
||||
display: inline-block;
|
||||
background: rgba(0, 255, 0, 0.08);
|
||||
border: 1px solid rgba(0, 255, 0, 0.25);
|
||||
color: var(--accent-color);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
padding: 7px 18px;
|
||||
border-radius: 50px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.ra-hero h1 {
|
||||
font-size: clamp(2.5rem, 5vw, 4rem);
|
||||
line-height: 1.1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ra-hero-sub {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.ra-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
max-width: 940px !important;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
.ra-section {
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ra-section-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
padding: 32px 40px 24px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.ra-icon {
|
||||
font-size: 1.8rem;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.ra-section-title {
|
||||
font-size: 1.5rem;
|
||||
color: #fff;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ra-section-badge {
|
||||
display: inline-block;
|
||||
background: rgba(0, 255, 0, 0.07);
|
||||
border: 1px solid rgba(0, 255, 0, 0.2);
|
||||
color: var(--accent-color);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
padding: 4px 12px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
.ra-section-body {
|
||||
padding: 32px 40px;
|
||||
}
|
||||
|
||||
/* Budget allocation */
|
||||
.ra-alloc {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.ra-alloc-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ra-alloc-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ra-alloc-label {
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.ra-alloc-amount {
|
||||
font-weight: 800;
|
||||
color: var(--accent-color);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.ra-progress-track {
|
||||
height: 6px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: 99px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ra-progress-bar {
|
||||
height: 100%;
|
||||
background: var(--accent-gradient);
|
||||
border-radius: 99px;
|
||||
transition: width 0.8s ease;
|
||||
}
|
||||
|
||||
.ra-alloc-desc {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.88rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Text blocks */
|
||||
.ra-text-block p {
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.8;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.ra-highlight {
|
||||
color: var(--accent-color);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.ra-list {
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.9;
|
||||
padding-left: 20px;
|
||||
margin: 12px 0 24px;
|
||||
}
|
||||
|
||||
.ra-list li::marker {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
/* Phase grid */
|
||||
.ra-phase-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.ra-phase {
|
||||
background: rgba(0,255,0,0.03);
|
||||
border: 1px solid rgba(0,255,0,0.1);
|
||||
border-radius: 14px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.ra-phase-num {
|
||||
display: inline-block;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--accent-color);
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ra-phase strong {
|
||||
display: block;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ra-phase p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Business Model */
|
||||
.ra-bm-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.ra-bm-card {
|
||||
padding: 24px;
|
||||
border-radius: 14px !important;
|
||||
}
|
||||
|
||||
.ra-bm-title {
|
||||
font-size: 1.05rem;
|
||||
color: #fff;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.ra-bm-sub {
|
||||
font-size: 0.82rem;
|
||||
color: var(--accent-color);
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.ra-bm-desc {
|
||||
font-size: 0.9rem;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Traction */
|
||||
.ra-traction-stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.ra-traction-stats { grid-template-columns: repeat(2, 1fr); }
|
||||
.ra-section-header { flex-direction: column; padding: 24px; }
|
||||
.ra-section-body { padding: 24px; }
|
||||
}
|
||||
|
||||
.ra-tstat {
|
||||
background: rgba(255,255,255,0.02);
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
border-radius: 14px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ra-tstat-val {
|
||||
display: block;
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ra-tstat-label {
|
||||
font-size: 0.82rem;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
|
||||
.ra-traction-note {
|
||||
background: rgba(0,255,0,0.04);
|
||||
border-left: 3px solid var(--accent-color);
|
||||
padding: 14px 18px;
|
||||
border-radius: 0 10px 10px 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.7;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Values */
|
||||
.ra-values-list li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* Download */
|
||||
.ra-download {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 24px;
|
||||
padding: 36px 40px;
|
||||
border-radius: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ra-download-text h3 {
|
||||
font-size: 1.3rem;
|
||||
color: #fff;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.ra-download-text p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Meeting CTA */
|
||||
.ra-meeting {
|
||||
text-align: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.ra-meeting p {
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
import React from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import './RestrictedArea.css';
|
||||
|
||||
const SECTIONS = [
|
||||
{
|
||||
id: 'investition',
|
||||
icon: '€',
|
||||
title: 'Kapitalbedarf: Tranche 1',
|
||||
badge: '150.000 € Stille Beteiligung · Zielrendite 10%',
|
||||
content: (
|
||||
<div className="ra-alloc">
|
||||
{[
|
||||
{ label: 'Runway & Liquiditätspuffer', amount: '70.000 €', pct: 47, desc: 'Absicherung der Skalierungsphase.' },
|
||||
{ label: 'Go-to-Market', amount: '50.000 €', pct: 33, desc: 'Sales, Messen, Multiplikatoren.' },
|
||||
{ label: 'Legal & Zertifizierungen', amount: '30.000 €', pct: 20, desc: 'ISO 27001 / DSGVO-Compliance.' },
|
||||
].map(({ label, amount, pct, desc }) => (
|
||||
<div key={label} className="ra-alloc-row">
|
||||
<div className="ra-alloc-meta">
|
||||
<span className="ra-alloc-label">{label}</span>
|
||||
<span className="ra-alloc-amount">{amount}</span>
|
||||
</div>
|
||||
<div className="ra-progress-track">
|
||||
<div className="ra-progress-bar" style={{ width: `${pct}%` }} />
|
||||
</div>
|
||||
<p className="ra-alloc-desc">{desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'markt',
|
||||
icon: '📈',
|
||||
title: 'Marktchance & Positionierung',
|
||||
badge: 'Europäischer Mittelstand',
|
||||
content: (
|
||||
<div className="ra-text-block">
|
||||
<p>Europas Mittelstand steht einem fundamentalen Dilemma gegenüber: Die KI-Revolution läuft, doch die sichere, compliant-fähige Infrastruktur fehlt. US-Hyperscaler (OpenAI, Google) scheiden aus regulatorischen und sicherheitstechnischen Gründen aus.</p>
|
||||
<p>Project KIQ besetzt genau diese Lücke. Als <strong className="ra-highlight">souveränes KI-Betriebssystem</strong> für den europäischen Mittelstand liefert es:</p>
|
||||
<ul className="ra-list">
|
||||
<li>100% DSGVO & AI-Act Konformität von Anfang an</li>
|
||||
<li>Kein Vendor-Lock-in durch US-Hyperscaler</li>
|
||||
<li>Plug-and-Play Deployment ohne eigenes IT-Team</li>
|
||||
<li>Wissenschaftliche Begleitung durch Universität Kassel</li>
|
||||
</ul>
|
||||
<div className="ra-phase-grid">
|
||||
<div className="ra-phase">
|
||||
<span className="ra-phase-num">Phase 1</span>
|
||||
<strong>Pretotyping & MVP</strong>
|
||||
<p>3–5 Pilotpartner, je bis zu 6 TEUR Förderung. Schnelle Entwicklung eines minimal testbaren Produkts.</p>
|
||||
</div>
|
||||
<div className="ra-phase">
|
||||
<span className="ra-phase-num">Phase 2</span>
|
||||
<strong>Produktionsumgebung</strong>
|
||||
<p>Skalierbare KI-Infrastruktur, Landesförderung, laufende Kostenbeteiligung. Perspektivisch eigene Hardware.</p>
|
||||
</div>
|
||||
<div className="ra-phase">
|
||||
<span className="ra-phase-num">Phase 3</span>
|
||||
<strong>200 Kunden in 24 Monaten</strong>
|
||||
<p>Aufbau dediziertes B2B-Sales-Team, Expansion über öffentliche Träger & Wirtschaftsförderung als Multiplikatoren.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'geschaeftsmodell',
|
||||
icon: '💡',
|
||||
title: 'Geschäftsmodell & Revenue',
|
||||
badge: 'Dreistufig · Skalierbar',
|
||||
content: (
|
||||
<div className="ra-bm-grid">
|
||||
{[
|
||||
{ title: 'Setup-Fee', sub: 'Einmalig ~2.500 €', desc: 'Deckt Onboarding & Schnittstellen-Anbindung. Deckt sofort Vertriebsaufwände.' },
|
||||
{ title: 'Token-Marge (MRR)', sub: 'Monatlich, nutzungsbasiert', desc: '20–50% Marge auf Server/Token-Kosten. Hochgradig skalierbar ohne Einstiegshürde.' },
|
||||
{ title: 'Developer 80/20', sub: 'Plattform-Abgabe', desc: 'Externe Entwickler behalten 80% Gewinn. 20% finanzieren Plattform-Betrieb dauerhaft.' },
|
||||
].map(({ title, sub, desc }) => (
|
||||
<div key={title} className="ra-bm-card glass-panel">
|
||||
<h4 className="ra-bm-title">{title}</h4>
|
||||
<p className="ra-bm-sub">{sub}</p>
|
||||
<p className="ra-bm-desc">{desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'traction',
|
||||
icon: '🚀',
|
||||
title: 'Traction & Proof of Concept',
|
||||
badge: 'Bereits profitabel im Testbetrieb',
|
||||
content: (
|
||||
<div className="ra-traction">
|
||||
<div className="ra-traction-stats">
|
||||
{[
|
||||
{ val: '6', label: 'Zahlende Pilotkunden' },
|
||||
{ val: '60k€', label: 'Initialumsatz geflossen' },
|
||||
{ val: '12+', label: 'Aktive Use Cases' },
|
||||
{ val: 'M15', label: 'Break-Even Prognose' },
|
||||
].map(({ val, label }) => (
|
||||
<div key={label} className="ra-tstat">
|
||||
<span className="ra-tstat-val text-gradient">{val}</span>
|
||||
<span className="ra-tstat-label">{label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p className="ra-traction-note">Identifizierte Use Cases aus dem laufenden Betrieb: Teileerkennung, Prüfprotokolle, Marktanalyse, Angebotsunterstützung, Berichtserzeugung, Wissensmanagement.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'strategie',
|
||||
icon: '🏛',
|
||||
title: 'Governance & Fundamentale Werte',
|
||||
badge: 'Verfassung v0.2',
|
||||
content: (
|
||||
<div className="ra-text-block">
|
||||
<p>Project KIQ wird als modernes, krisenfestes Unternehmen für Top-Talente gebaut. Kernprinzipien aus der bindenden Verfassung:</p>
|
||||
<ul className="ra-list ra-values-list">
|
||||
{[
|
||||
'Souveränität: Datensouveränität der Kunden ist das höchste Gut.',
|
||||
'Null-Veto-Politik: Psychologische Sicherheit bei Kunden- & Teamaufnahme.',
|
||||
'Solidarisches Entlohnungsmodell: Existenzsicherndes Basisgehalt plus Gewinnbeteiligung.',
|
||||
'Pragmatismus: „Robust > fancy" – Keep it simple & stupid.',
|
||||
'Transparenz: Offene Gehaltspolitik & Open-Source-Kodex intern.',
|
||||
].map(v => <li key={v}>{v}</li>)}
|
||||
</ul>
|
||||
<p>Zielstruktur: <strong className="ra-highlight">GmbH & Co. KG</strong> – operatives Geschäft sauber von Investitionskapital getrennt. Investoren als Stille Teilhaber ohne Einfluss auf Verfassungsprinzipien.</p>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function RestrictedArea() {
|
||||
const navigate = useNavigate();
|
||||
const { logout } = useAuth();
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout();
|
||||
navigate('/');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="ra-page">
|
||||
<div className="ra-hero">
|
||||
<div className="hero-glow background-mesh" />
|
||||
<div className="ra-hero-content">
|
||||
<div className="res-header-row">
|
||||
<span className="ra-badge">🔒 Geschützter Bereich</span>
|
||||
<button onClick={handleLogout} className="logout-btn">Abmelden</button>
|
||||
</div>
|
||||
<h1>Investor <span className="text-gradient">Relations</span></h1>
|
||||
<p className="ra-hero-sub">Confidential Business Case, Marktchance & Investment-Unterlagen für Project KIQ.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="ra-container app-container">
|
||||
{SECTIONS.map(({ id, icon, title, badge, content }) => (
|
||||
<section key={id} className="ra-section glass-panel">
|
||||
<div className="ra-section-header">
|
||||
<div className="ra-icon">{icon}</div>
|
||||
<div>
|
||||
<h2 className="ra-section-title">{title}</h2>
|
||||
<span className="ra-section-badge">{badge}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ra-section-body">{content}</div>
|
||||
</section>
|
||||
))}
|
||||
|
||||
{/* Document notice (replaces PDF download) */}
|
||||
<div className="ra-download glass-panel">
|
||||
<div className="ra-download-text">
|
||||
<h3>Pitch Deck & Unterlagen</h3>
|
||||
<p>Das vollständige Pitch Deck mit allen Finanz-Projektionen und technischen Details wird Ihnen nach Genehmigung per E-Mail bereitgestellt.</p>
|
||||
</div>
|
||||
<span className="ra-doc-notice">📧 Dokumente werden per E-Mail bereitgestellt</span>
|
||||
</div>
|
||||
|
||||
{/* CTA to request meeting */}
|
||||
<div className="ra-meeting">
|
||||
<p>Bereit für das nächste Gespräch?</p>
|
||||
<Link to="/request-access" className="primary-button">Gespräch anfragen →</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
.uc-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
|
||||
/* Hero */
|
||||
.uc-hero {
|
||||
position: relative;
|
||||
padding: 160px 20px 80px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uc-hero-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 780px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.uc-label-tag {
|
||||
display: inline-block;
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
border: 1px solid rgba(0, 255, 0, 0.3);
|
||||
color: var(--accent-color);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
padding: 6px 16px;
|
||||
border-radius: 50px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.uc-hero h1 {
|
||||
font-size: clamp(2.5rem, 5vw, 4rem);
|
||||
line-height: 1.1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.uc-subtitle {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* Context banner */
|
||||
.uc-context {
|
||||
padding: 24px 32px;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.uc-context p {
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
font-size: 0.95rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Container */
|
||||
.uc-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-top: 20px;
|
||||
max-width: 940px !important;
|
||||
}
|
||||
|
||||
/* Cards */
|
||||
.uc-card {
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
|
||||
.uc-card:hover {
|
||||
border-color: rgba(0, 255, 0, 0.2);
|
||||
}
|
||||
|
||||
.uc-card-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
padding: 32px 40px 24px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.uc-card-meta {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.uc-icon {
|
||||
font-size: 2rem;
|
||||
flex-shrink: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.uc-status {
|
||||
display: inline-block;
|
||||
background: rgba(0,255,0,0.1);
|
||||
border: 1px solid rgba(0,255,0,0.25);
|
||||
color: var(--accent-color);
|
||||
font-size: 0.73rem;
|
||||
font-weight: 700;
|
||||
padding: 3px 10px;
|
||||
border-radius: 50px;
|
||||
letter-spacing: 0.06em;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.uc-title {
|
||||
font-size: 1.5rem;
|
||||
color: #fff;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.uc-tagline {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.95rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.uc-number {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 800;
|
||||
color: rgba(0,255,0,0.08);
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Card body */
|
||||
.uc-card-body {
|
||||
padding: 28px 40px;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: 680px) {
|
||||
.uc-card-body { grid-template-columns: 1fr; }
|
||||
.uc-card-header { flex-direction: column; gap: 12px; padding: 24px; }
|
||||
.uc-card-body { padding: 24px; gap: 20px; }
|
||||
.uc-number { font-size: 2.5rem; }
|
||||
}
|
||||
|
||||
.uc-detail-block h3,
|
||||
.uc-outcome-block h3 {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.uc-detail-block p,
|
||||
.uc-outcome-block p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.92rem;
|
||||
line-height: 1.7;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.uc-outcome-block {
|
||||
background: rgba(0,255,0,0.03);
|
||||
border: 1px solid rgba(0,255,0,0.08);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.uc-outcome-block h3 {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.uc-outcome-block p {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* CTA */
|
||||
.uc-cta {
|
||||
margin-top: 60px;
|
||||
max-width: 940px !important;
|
||||
}
|
||||
|
||||
.uc-cta-inner {
|
||||
padding: 56px 48px;
|
||||
border-radius: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uc-cta-inner h2 {
|
||||
font-size: clamp(1.4rem, 3vw, 2rem);
|
||||
color: #fff;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.uc-cta-inner p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1rem;
|
||||
line-height: 1.7;
|
||||
max-width: 560px;
|
||||
margin: 0 auto 32px;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { USE_CASES } from '../data/useCases';
|
||||
import './UseCases.css';
|
||||
|
||||
export default function UseCases() {
|
||||
return (
|
||||
<div className="uc-page">
|
||||
{/* Hero */}
|
||||
<div className="uc-hero">
|
||||
<div className="hero-glow background-mesh" />
|
||||
<div className="uc-hero-content">
|
||||
<span className="uc-label-tag">Projektergebnisse</span>
|
||||
<h1>Bewiesene <span className="text-gradient">Use Cases</span></h1>
|
||||
<p className="uc-subtitle">
|
||||
Im Rahmen des Projekts „KI für KMU" (Transformationsnetzwerk Region Kassel) wurden gemeinsam mit Praxispartnern fünf KI-Agenten erfolgreich entwickelt und eingesetzt. Hier sind die Ergebnisse.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Context Banner */}
|
||||
<div className="app-container">
|
||||
<div className="uc-context glass-panel">
|
||||
<p>
|
||||
<strong style={{ color: '#fff' }}>Ausgangslage:</strong> Viele Unternehmen wollen KI einsetzen, scheitern aber an fehlenden Leitplanken, Sicherheitsbedenken und unkoordinierten Eigenversuchen mit US-basierten SaaS-Lösungen.
|
||||
Project KIQ liefert die Infrastruktur für <strong style={{ color: '#fff' }}>kontrollierte, sichere und regelkonforme</strong> KI — und diese fünf Use Cases belegen, dass es funktioniert.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Use Cases */}
|
||||
<div className="uc-container app-container">
|
||||
{USE_CASES.map((uc, i) => (
|
||||
<article key={uc.id} className="uc-card glass-panel">
|
||||
<div className="uc-card-header">
|
||||
<div className="uc-card-meta">
|
||||
<span className="uc-icon">{uc.icon}</span>
|
||||
<div>
|
||||
<span className="uc-status">✓ {uc.status}</span>
|
||||
<h2 className="uc-title">{uc.title}</h2>
|
||||
<p className="uc-tagline">{uc.tagline}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span className="uc-number">0{i + 1}</span>
|
||||
</div>
|
||||
|
||||
<div className="uc-card-body">
|
||||
<div className="uc-detail-block">
|
||||
<h3>Wie es funktioniert</h3>
|
||||
<p>{uc.detail}</p>
|
||||
</div>
|
||||
<div className="uc-outcome-block">
|
||||
<h3>Ergebnis</h3>
|
||||
<p>{uc.outcome}</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div className="uc-cta app-container">
|
||||
<div className="uc-cta-inner glass-panel">
|
||||
<h2>Bereit, einen Use Case in Ihrem Unternehmen umzusetzen?</h2>
|
||||
<p>Wir zeigen Ihnen, welcher Use Case zu Ihrem Unternehmen passt — in einem ersten, unverbindlichen Gespräch.</p>
|
||||
<Link to="/request-access" className="primary-button">Gespräch anfragen →</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user