/* global React */ // Pages: Blog (loads from blog.json), Blog Detail, Jobs, Kontakt function useBlogPosts() { const [posts, setPosts] = useState(null); const [err, setErr] = useState(null); useEffect(() => { fetch('blog.json') .then(r => { if (!r.ok) throw new Error('HTTP '+r.status); return r.json(); }) .then(setPosts) .catch(e => setErr(e.message)); }, []); return { posts, err }; } function formatDate(iso) { const [y, m, d] = iso.split('-'); return `${d}.${m}.${y.slice(2)}`; } function BlogPage() { const { posts, err } = useBlogPosts(); return (
{err &&

Konnte Blog-Einträge nicht laden ({err}).

} {!posts && !err &&

Lade Artikel…

} {posts && (
{posts.map((p) => (
{formatDate(p.date)}

{p.title}

{p.excerpt}

{p.tags && (
{p.tags.map(t => {t})}
)}
))}
)}
); } function BlogDetailPage({ slug }) { const { posts, err } = useBlogPosts(); const post = posts?.find(p => p.slug === slug); return (
{err &&

Fehler beim Laden.

} {!posts && !err &&

Lade…

} {posts && !post && (

Artikel nicht gefunden.

Zurück zum Blog
)} {post && ( <>
{post.body}
{post.tags && (
{post.tags.map(t => {t})}
)}
← Alle Artikel
)}
); } function JobsPage() { const jobs = [ { t: 'Senior Systemadministrator', typ: 'Vollzeit', level: 'Senior', ort: 'Hamburg / Hybrid', d: 'Verantwortung für Kundensysteme, 2nd/3rd-Level, Projektleitung kleinerer Rollouts. Sie arbeiten direkt mit festen Kunden — Ticket-System ist ein Werkzeug, nicht Ihr Leben.' }, { t: 'IT-Mitarbeiter 1st-Level-Support', typ: 'Vollzeit', level: 'Junior–Mid', ort: 'Hamburg', d: 'Erste Anlaufstelle für unsere Kunden. Telefon, Mail, Teamviewer. Sie lösen, was lösbar ist — und geben strukturiert ab, was weiter muss.' }, { t: 'Junior System- / Netzwerk-Administrator', typ: 'Vollzeit', level: 'Junior', ort: 'Hamburg', d: 'Einstieg mit Mentoring. Sie wachsen mit realen Projekten und festen Ansprechpartnern — nicht in einer anonymen Lern-Pipeline.' }, ]; return (
{jobs.map((j, i) => (
{j.ort}

{j.t} (m/w/d)

{j.d}

{j.typ} {j.level} Festanstellung
Bewerben
))}

Nichts Passendes dabei?
Initiativbewerbungen sind willkommen — wir lesen jede.

jobs@4its.de
); } function KontaktPage() { const [state, setState] = useState({ name:'', company:'', email:'', phone:'', topic:'service', message:'', consent:false, website:'', ts: Math.floor(Date.now()/1000) }); const [errors, setErrors] = useState({}); const [sent, setSent] = useState(false); const [sending, setSending] = useState(false); const [submitError, setSubmitError] = useState(''); const set = (k) => (e) => setState(s => ({ ...s, [k]: e.target.type === 'checkbox' ? e.target.checked : e.target.value })); const submit = async (e) => { e.preventDefault(); setSubmitError(''); const err = {}; if (!state.name.trim()) err.name = 'Bitte Name angeben'; if (!state.email.match(/^[^@\s]+@[^@\s]+\.[^@\s]+$/)) err.email = 'Gültige Mail-Adresse'; if (!state.message.trim() || state.message.length < 10) err.message = 'Mindestens 10 Zeichen'; if (!state.consent) err.consent = 'Bitte bestätigen'; setErrors(err); if (Object.keys(err).length > 0) return; setSending(true); try { const res = await fetch('contact.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(state), }); const data = await res.json().catch(() => ({})); if (res.ok && data.ok) { setSent(true); } else if (res.status === 422 && data.errors) { setErrors(data.errors); } else if (res.status === 429) { setSubmitError('Zu viele Anfragen von Ihrer Adresse. Bitte versuchen Sie es in einigen Minuten erneut — oder rufen Sie uns direkt an: +49 40 561947 0'); } else { setSubmitError('Leider ist beim Senden etwas schiefgelaufen. Bitte rufen Sie uns an: +49 40 561947 0'); } } catch (_) { setSubmitError('Netzwerkfehler. Bitte rufen Sie uns an: +49 40 561947 0'); } finally { setSending(false); } }; return (
So erreichen Sie uns

Direkt & ohne Umwege.

Adresse
Burchardstraße 22
20095 Hamburg
Bürozeiten
Mo – Fr · 09:00 – 18:00 Uhr
Alle anderen Zeiten: Kunden-Hotline
Fernwartung · Teamviewer
{sent ? (

Vielen Dank, {state.name.split(' ')[0]}!

Wir haben Ihre Nachricht erhalten und melden uns innerhalb eines Werktags.

) : (
{errors.name}
{errors.email}