refactor: estimation generation
All checks were successful
Build & Deploy / 🔍 Prepare Environment (push) Successful in 32s
Build & Deploy / 🏗️ Build (push) Successful in 4m41s
Build & Deploy / 🧪 QA (push) Successful in 5m56s
Build & Deploy / 🚀 Deploy (push) Successful in 12s
Build & Deploy / 🔔 Notifications (push) Successful in 1s
Build & Deploy / ⚡ PageSpeed (push) Successful in 55s

This commit is contained in:
2026-02-09 19:11:02 +01:00
parent f4ba861b4d
commit e6809a6d64
17 changed files with 3788 additions and 1805 deletions

View File

@@ -1,202 +1,224 @@
import { FormState, Position, Totals } from './types';
import { FEATURE_LABELS, FUNCTION_LABELS, API_LABELS, PAGE_LABELS } from './constants';
import { FormState, Position, Totals } from "./types";
import {
FEATURE_LABELS,
FUNCTION_LABELS,
API_LABELS,
PAGE_LABELS,
} from "./constants";
export function calculateTotals(state: FormState, pricing: any): Totals {
if (state.projectType !== 'website') {
return {
totalPrice: 0,
monthlyPrice: 0,
totalPagesCount: 0,
totalFeatures: 0,
totalFunctions: 0,
totalApis: 0,
languagesCount: 0
};
}
const sitemapPagesCount = state.sitemap?.reduce((acc: number, cat: any) => acc + (cat.pages?.length || 0), 0) || 0;
const totalPagesCount = Math.max(
(state.selectedPages?.length || 0) + (state.otherPages?.length || 0) + (state.otherPagesCount || 0),
sitemapPagesCount
);
const totalFeatures = (state.features?.length || 0) + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0);
const totalFunctions = (state.functions?.length || 0) + (state.otherFunctions?.length || 0) + (state.otherFunctionsCount || 0);
const totalApis = (state.apiSystems?.length || 0) + (state.otherTech?.length || 0) + (state.otherTechCount || 0);
let total = pricing.BASE_WEBSITE;
total += totalPagesCount * pricing.PAGE;
total += totalFeatures * pricing.FEATURE;
total += totalFunctions * pricing.FUNCTION;
total += totalApis * pricing.API_INTEGRATION;
total += (state.newDatasets || 0) * pricing.NEW_DATASET;
if (state.cmsSetup) {
total += pricing.CMS_SETUP;
total += totalFeatures * pricing.CMS_CONNECTION_PER_FEATURE;
}
// Optional visual/complexity boosters (from calculator.ts logic)
if (state.visualStaging && !isNaN(Number(state.visualStaging)) && Number(state.visualStaging) > 0) {
total += Number(state.visualStaging) * pricing.VISUAL_STAGING;
}
if (state.complexInteractions && !isNaN(Number(state.complexInteractions)) && Number(state.complexInteractions) > 0) {
total += Number(state.complexInteractions) * pricing.COMPLEX_INTERACTION;
}
const languagesCount = state.languagesList?.length || 1;
if (languagesCount > 1) {
total *= (1 + (languagesCount - 1) * 0.2);
}
const monthlyPrice = pricing.HOSTING_MONTHLY + ((state.storageExpansion || 0) * pricing.STORAGE_EXPANSION_MONTHLY);
if (state.projectType !== "website") {
return {
totalPrice: Math.round(total),
monthlyPrice: Math.round(monthlyPrice),
totalPagesCount,
totalFeatures,
totalFunctions,
totalApis,
languagesCount
totalPrice: 0,
monthlyPrice: 0,
totalPagesCount: 0,
totalFeatures: 0,
totalFunctions: 0,
totalApis: 0,
languagesCount: 0,
};
}
const sitemapPagesCount =
state.sitemap?.reduce(
(acc: number, cat: any) => acc + (cat.pages?.length || 0),
0,
) || 0;
const totalPagesCount = Math.max(
(state.selectedPages?.length || 0) +
(state.otherPages?.length || 0) +
(state.otherPagesCount || 0),
sitemapPagesCount,
);
const totalFeatures =
(state.features?.length || 0) +
(state.otherFeatures?.length || 0) +
(state.otherFeaturesCount || 0);
const totalFunctions =
(state.functions?.length || 0) +
(state.otherFunctions?.length || 0) +
(state.otherFunctionsCount || 0);
const totalApis =
(state.apiSystems?.length || 0) +
(state.otherTech?.length || 0) +
(state.otherTechCount || 0);
let total = pricing.BASE_WEBSITE;
total += totalPagesCount * pricing.PAGE;
total += totalFeatures * pricing.FEATURE;
total += totalFunctions * pricing.FUNCTION;
total += totalApis * pricing.API_INTEGRATION;
total += (state.newDatasets || 0) * pricing.NEW_DATASET;
if (state.cmsSetup) {
total += Math.max(1, totalFeatures) * pricing.CMS_CONNECTION_PER_FEATURE;
}
const languagesCount = state.languagesList?.length || 1;
if (languagesCount > 1) {
total *= 1 + (languagesCount - 1) * 0.2;
}
const monthlyPrice =
pricing.HOSTING_MONTHLY +
(state.storageExpansion || 0) * pricing.STORAGE_EXPANSION_MONTHLY;
return {
totalPrice: Math.round(total),
monthlyPrice: Math.round(monthlyPrice),
totalPagesCount,
totalFeatures,
totalFunctions,
totalApis,
languagesCount,
};
}
export function calculatePositions(state: FormState, pricing: any): Position[] {
const positions: Position[] = [];
let pos = 1;
const positions: Position[] = [];
let pos = 1;
if (state.projectType === 'website') {
positions.push({
pos: pos++,
title: 'Das technische Fundament',
desc: 'Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.',
qty: 1,
price: pricing.BASE_WEBSITE
});
if (state.projectType === "website") {
positions.push({
pos: pos++,
title: "Das technische Fundament",
desc: "Projekt-Setup, Infrastruktur, Hosting-Bereitstellung, Grundstruktur & Design-Vorlage, technisches SEO-Basics, Analytics.",
qty: 1,
price: pricing.BASE_WEBSITE,
});
const sitemapPagesCount = state.sitemap?.reduce((acc: number, cat: any) => acc + (cat.pages?.length || 0), 0) || 0;
const totalPagesCount = Math.max(
(state.selectedPages?.length || 0) + (state.otherPages?.length || 0) + (state.otherPagesCount || 0),
sitemapPagesCount
);
const sitemapPagesCount =
state.sitemap?.reduce(
(acc: number, cat: any) => acc + (cat.pages?.length || 0),
0,
) || 0;
const totalPagesCount = Math.max(
(state.selectedPages?.length || 0) +
(state.otherPages?.length || 0) +
(state.otherPagesCount || 0),
sitemapPagesCount,
);
const allPages = [
...(state.selectedPages || []).map((p: string) => PAGE_LABELS[p] || p),
...(state.otherPages || []),
...(state.sitemap?.flatMap((cat: any) => cat.pages?.map((p: any) => p.title)) || [])
];
const allPages = [
...(state.selectedPages || []).map((p: string) => PAGE_LABELS[p] || p),
...(state.otherPages || []),
...(state.sitemap?.flatMap((cat: any) =>
cat.pages?.map((p: any) => p.title),
) || []),
];
// Deduplicate labels
const uniquePages = Array.from(new Set(allPages));
// Deduplicate labels
const uniquePages = Array.from(new Set(allPages));
positions.push({
pos: pos++,
title: 'Individuelle Seiten',
desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(', ')}).`,
qty: totalPagesCount,
price: totalPagesCount * pricing.PAGE
});
positions.push({
pos: pos++,
title: "Individuelle Seiten",
desc: `Gestaltung und Umsetzung von ${totalPagesCount} individuellen Seiten-Layouts (${uniquePages.join(", ")}).`,
qty: totalPagesCount,
price: totalPagesCount * pricing.PAGE,
});
if (state.features.length > 0 || (state.otherFeatures?.length || 0) > 0) {
const allFeatures = [...state.features.map((f: string) => FEATURE_LABELS[f] || f), ...(state.otherFeatures || [])];
positions.push({
pos: pos++,
title: 'System-Module (Features)',
desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(', ')}. Inklusive Datenstruktur und Darstellung.`,
qty: allFeatures.length,
price: allFeatures.length * pricing.FEATURE
});
}
if (state.functions.length > 0 || (state.otherFunctions?.length || 0) > 0) {
const allFunctions = [...state.functions.map((f: string) => FUNCTION_LABELS[f] || f), ...(state.otherFunctions || [])];
positions.push({
pos: pos++,
title: 'Logik-Funktionen',
desc: `Implementierung technischer Logik: ${allFunctions.join(', ')}.`,
qty: allFunctions.length,
price: allFunctions.length * pricing.FUNCTION
});
}
if (state.apiSystems.length > 0 || (state.otherTech?.length || 0) > 0) {
const allApis = [...state.apiSystems.map((a: string) => API_LABELS[a] || a), ...(state.otherTech || [])];
positions.push({
pos: pos++,
title: 'Schnittstellen (API)',
desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(', ')}.`,
qty: allApis.length,
price: allApis.length * pricing.API_INTEGRATION
});
}
if (state.cmsSetup) {
const totalFeatures = state.features.length + (state.otherFeatures?.length || 0) + (state.otherFeaturesCount || 0);
positions.push({
pos: pos++,
title: 'Inhaltsverwaltung (CMS)',
desc: 'Einrichtung eines Systems zur eigenständigen Pflege von Inhalten und Datensätzen.',
qty: 1,
price: pricing.CMS_SETUP + totalFeatures * pricing.CMS_CONNECTION_PER_FEATURE
});
}
if (state.newDatasets > 0) {
positions.push({
pos: pos++,
title: 'Inhaltliche Initial-Pflege',
desc: `Manuelle Übernahme und Aufbereitung von ${state.newDatasets} Datensätzen (Produkte, Artikel) in das Zielsystem.`,
qty: state.newDatasets,
price: state.newDatasets * pricing.NEW_DATASET
});
}
if ((state.visualStaging && Number(state.visualStaging) > 0) || (state.complexInteractions && Number(state.complexInteractions) > 0)) {
const vsCount = Number(state.visualStaging || 0);
const ciCount = Number(state.complexInteractions || 0);
const totalCount = vsCount + ciCount;
positions.push({
pos: pos++,
title: 'Inszenierung & Interaktion',
desc: `Umsetzung von ${totalCount} speziellen Sektionen, Hero-Stories oder Konfiguratoren zur Steigerung der Conversion.`,
qty: totalCount,
price: (vsCount * pricing.VISUAL_STAGING) + (ciCount * pricing.COMPLEX_INTERACTION)
});
}
const languagesCount = state.languagesList.length || 1;
if (languagesCount > 1) {
const subtotal = positions.reduce((sum, p) => sum + p.price, 0);
const factorPrice = subtotal * ((languagesCount - 1) * 0.2);
positions.push({
pos: pos++,
title: 'Mehrsprachigkeit',
desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`,
qty: languagesCount,
price: Math.round(factorPrice)
});
}
const monthlyRate = pricing.HOSTING_MONTHLY + (state.storageExpansion * pricing.STORAGE_EXPANSION_MONTHLY);
positions.push({
pos: pos++,
title: 'Sorglos-Paket (Betrieb & Pflege)',
desc: `1 Jahr Sicherung des technischen Betriebs, Instandhaltung, Sicherheits-Updates und Inhalts-Aktualisierungen gemäß AGB Punkt 7a.`,
qty: 1,
price: monthlyRate * 12
});
} else {
positions.push({
pos: pos++,
title: 'Web App / Software Entwicklung',
desc: 'Individuelle Software-Entwicklung nach Aufwand. Abrechnung erfolgt auf Stundenbasis.',
qty: 1,
price: 0
});
if (state.features.length > 0 || (state.otherFeatures?.length || 0) > 0) {
const allFeatures = [
...state.features.map((f: string) => FEATURE_LABELS[f] || f),
...(state.otherFeatures || []),
];
positions.push({
pos: pos++,
title: "System-Module (Features)",
desc: `Implementierung funktionaler Bereiche: ${allFeatures.join(", ")}. Inklusive Datenstruktur und Darstellung.`,
qty: allFeatures.length,
price: allFeatures.length * pricing.FEATURE,
});
}
return positions;
if (state.functions.length > 0 || (state.otherFunctions?.length || 0) > 0) {
const allFunctions = [
...state.functions.map((f: string) => FUNCTION_LABELS[f] || f),
...(state.otherFunctions || []),
];
positions.push({
pos: pos++,
title: "Logik-Funktionen",
desc: `Implementierung technischer Logik: ${allFunctions.join(", ")}.`,
qty: allFunctions.length,
price: allFunctions.length * pricing.FUNCTION,
});
}
if (state.apiSystems.length > 0 || (state.otherTech?.length || 0) > 0) {
const allApis = [
...state.apiSystems.map((a: string) => API_LABELS[a] || a),
...(state.otherTech || []),
];
positions.push({
pos: pos++,
title: "Schnittstellen (API)",
desc: `Anbindung externer Systeme zur Datensynchronisation: ${allApis.join(", ")}.`,
qty: allApis.length,
price: allApis.length * pricing.API_INTEGRATION,
});
}
if (state.cmsSetup) {
const totalFeatures =
state.features.length +
(state.otherFeatures?.length || 0) +
(state.otherFeaturesCount || 0);
const qty = Math.max(1, totalFeatures);
positions.push({
pos: pos++,
title: "Inhalts-Verwaltung",
desc: "Anbindung der System-Module an das Redaktions-System zur eigenständigen Pflege von Inhalten.",
qty: qty,
price: qty * pricing.CMS_CONNECTION_PER_FEATURE,
});
}
if (state.newDatasets > 0) {
positions.push({
pos: pos++,
title: "Inhaltliche Initial-Pflege",
desc: `Manuelle Übernahme und Aufbereitung von ${state.newDatasets} Datensätzen (Produkte, Artikel) in das Zielsystem.`,
qty: state.newDatasets,
price: state.newDatasets * pricing.NEW_DATASET,
});
}
const languagesCount = state.languagesList.length || 1;
if (languagesCount > 1) {
const subtotal = positions.reduce((sum, p) => sum + p.price, 0);
const factorPrice = subtotal * ((languagesCount - 1) * 0.2);
positions.push({
pos: pos++,
title: "Mehrsprachigkeit",
desc: `Erweiterung des Systems auf ${languagesCount} Sprachen (Struktur & Logik).`,
qty: languagesCount,
price: Math.round(factorPrice),
});
}
const monthlyRate =
pricing.HOSTING_MONTHLY +
state.storageExpansion * pricing.STORAGE_EXPANSION_MONTHLY;
positions.push({
pos: pos++,
title: "Sorglos Betrieb (1 Jahr)",
desc: `Inklusive 1 Jahr Sicherung des technischen Betriebs, Hosting, Instandhaltung, Sicherheits-Updates und techn. Support gemäß AGB Punkt 7a.`,
qty: 1,
price: monthlyRate * 12,
});
} else {
positions.push({
pos: pos++,
title: "Web App / Software Entwicklung",
desc: "Individuelle Software-Entwicklung nach Aufwand. Abrechnung erfolgt auf Stundenbasis.",
qty: 1,
price: 0,
});
}
return positions;
}

View File

@@ -1,226 +1,332 @@
import { FormState } from './types';
import { FormState } from "./types";
export const PRICING = {
BASE_WEBSITE: 4000,
PAGE: 600,
FEATURE: 1500,
FUNCTION: 800,
NEW_DATASET: 200,
HOSTING_MONTHLY: 250,
STORAGE_EXPANSION_MONTHLY: 10,
CMS_SETUP: 1500,
CMS_CONNECTION_PER_FEATURE: 800,
API_INTEGRATION: 800,
APP_HOURLY: 120,
VISUAL_STAGING: 2000,
COMPLEX_INTERACTION: 1500,
BASE_WEBSITE: 4000,
PAGE: 600,
FEATURE: 1500,
FUNCTION: 800,
NEW_DATASET: 450,
HOSTING_MONTHLY: 250,
STORAGE_EXPANSION_MONTHLY: 10,
CMS_SETUP: 1500,
CMS_CONNECTION_PER_FEATURE: 1500,
API_INTEGRATION: 800,
APP_HOURLY: 120,
};
export const initialState: FormState = {
projectType: 'website',
// Company
companyName: '',
employeeCount: '',
// Existing Presence
existingWebsite: '',
socialMedia: [],
socialMediaUrls: {},
existingDomain: '',
wishedDomain: '',
// Project
websiteTopic: '',
selectedPages: ['Home'],
otherPages: [],
otherPagesCount: 0,
features: [],
otherFeatures: [],
otherFeaturesCount: 0,
functions: [],
otherFunctions: [],
otherFunctionsCount: 0,
apiSystems: [],
otherTech: [],
otherTechCount: 0,
assets: [],
otherAssets: [],
otherAssetsCount: 0,
newDatasets: 0,
cmsSetup: false,
storageExpansion: 0,
name: '',
email: '',
role: '',
message: '',
sitemapFile: null,
contactFiles: [],
// Design
designVibe: 'minimal',
colorScheme: ['#ffffff', '#f8fafc', '#0f172a'],
references: [],
designWishes: '',
// Maintenance
expectedAdjustments: 'low',
languagesList: ['Deutsch'],
personName: '',
// Timeline
deadline: 'flexible',
// Web App specific
targetAudience: 'internal',
userRoles: [],
dataSensitivity: 'standard',
platformType: 'web-only',
// Meta
dontKnows: [],
visualStaging: 'standard',
complexInteractions: 'standard',
// AI generated / Post-processed
briefingSummary: '',
designVision: '',
positionDescriptions: {},
taxId: '',
sitemap: [],
projectType: "website",
// Company
companyName: "",
employeeCount: "",
// Existing Presence
existingWebsite: "",
socialMedia: [],
socialMediaUrls: {},
existingDomain: "",
wishedDomain: "",
// Project
websiteTopic: "",
selectedPages: ["Home"],
otherPages: [],
otherPagesCount: 0,
features: [],
otherFeatures: [],
otherFeaturesCount: 0,
functions: [],
otherFunctions: [],
otherFunctionsCount: 0,
apiSystems: [],
otherTech: [],
otherTechCount: 0,
assets: [],
otherAssets: [],
otherAssetsCount: 0,
newDatasets: 0,
cmsSetup: false,
storageExpansion: 0,
name: "",
email: "",
role: "",
message: "",
sitemapFile: null,
contactFiles: [],
// Design
designVibe: "minimal",
colorScheme: ["#ffffff", "#f8fafc", "#0f172a"],
references: [],
designWishes: "",
// Maintenance
expectedAdjustments: "low",
languagesList: ["Deutsch"],
personName: "",
// Timeline
deadline: "flexible",
// Web App specific
targetAudience: "internal",
userRoles: [],
dataSensitivity: "standard",
platformType: "web-only",
// Meta
dontKnows: [],
visualStaging: "standard",
complexInteractions: "standard",
// AI generated / Post-processed
briefingSummary: "",
designVision: "",
positionDescriptions: {},
taxId: "",
sitemap: [],
};
export const PAGE_SAMPLES = [
{ id: 'Home', label: 'Startseite', desc: 'Der erste Eindruck Ihrer Marke.' },
{ id: 'About', label: 'Über uns', desc: 'Ihre Geschichte und Ihr Team.' },
{ id: 'Services', label: 'Leistungen', desc: 'Übersicht Ihres Angebots.' },
{ id: 'Contact', label: 'Kontakt', desc: 'Anlaufstelle für Ihre Kunden.' },
{ id: 'Landing', label: 'Landingpage', desc: 'Optimiert für Marketing-Kampagnen.' },
{ id: 'Legal', label: 'Rechtliches', desc: 'Impressum & Datenschutz.' },
{ id: "Home", label: "Startseite", desc: "Der erste Eindruck Ihrer Marke." },
{ id: "About", label: "Über uns", desc: "Ihre Geschichte und Ihr Team." },
{ id: "Services", label: "Leistungen", desc: "Übersicht Ihres Angebots." },
{ id: "Contact", label: "Kontakt", desc: "Anlaufstelle für Ihre Kunden." },
{
id: "Landing",
label: "Landingpage",
desc: "Optimiert für Marketing-Kampagnen.",
},
{ id: "Legal", label: "Rechtliches", desc: "Impressum & Datenschutz." },
];
export const FEATURE_OPTIONS = [
{ id: 'blog_news', label: 'Blog / News', desc: 'Ein Bereich für aktuelle Beiträge und Neuigkeiten.' },
{ id: 'products', label: 'Produktbereich', desc: 'Katalog Ihrer Leistungen oder Produkte.' },
{ id: 'jobs', label: 'Karriere / Jobs', desc: 'Stellenanzeigen und Bewerbungsoptionen.' },
{ id: 'refs', label: 'Referenzen / Cases', desc: 'Präsentation Ihrer Projekte.' },
{ id: 'events', label: 'Events / Termine', desc: 'Veranstaltungskalender.' },
{
id: "blog_news",
label: "Blog / News",
desc: "Ein Bereich für aktuelle Beiträge und Neuigkeiten.",
},
{
id: "products",
label: "Produktbereich",
desc: "Katalog Ihrer Leistungen oder Produkte.",
},
{
id: "jobs",
label: "Karriere / Jobs",
desc: "Stellenanzeigen und Bewerbungsoptionen.",
},
{
id: "refs",
label: "Referenzen / Cases",
desc: "Präsentation Ihrer Projekte.",
},
{ id: "events", label: "Events / Termine", desc: "Veranstaltungskalender." },
];
export const FUNCTION_OPTIONS = [
{ id: 'search', label: 'Suche', desc: 'Volltextsuche über alle Inhalte.' },
{ id: 'filter', label: 'Filter-Systeme', desc: 'Kategorisierung und Sortierung.' },
{ id: 'pdf', label: 'PDF-Export', desc: 'Automatisierte PDF-Erstellung.' },
{ id: 'forms', label: 'Individuelle Formular-Logik', desc: 'Smarte Validierung & mehrstufige Prozesse.' },
{ id: "search", label: "Suche", desc: "Volltextsuche über alle Inhalte." },
{
id: "filter",
label: "Filter-Systeme",
desc: "Kategorisierung und Sortierung.",
},
{ id: "pdf", label: "PDF-Export", desc: "Automatisierte PDF-Erstellung." },
{
id: "forms",
label: "Individuelle Formular-Logik",
desc: "Smarte Validierung & mehrstufige Prozesse.",
},
];
export const API_OPTIONS = [
{ id: 'crm', label: 'CRM System', desc: 'HubSpot, Salesforce, Pipedrive etc.' },
{ id: 'erp', label: 'ERP / Warenwirtschaft', desc: 'SAP, Microsoft Dynamics, Xentral etc.' },
{ id: 'stripe', label: 'Stripe / Payment', desc: 'Zahlungsabwicklung und Abonnements.' },
{ id: 'newsletter', label: 'Newsletter / Marketing', desc: 'Mailchimp, Brevo, ActiveCampaign etc.' },
{ id: 'ecommerce', label: 'E-Commerce / Shop', desc: 'Shopify, WooCommerce, Shopware Sync.' },
{ id: 'hr', label: 'HR / Recruiting', desc: 'Personio, Workday, Recruitee etc.' },
{ id: 'realestate', label: 'Immobilien', desc: 'OpenImmo, FlowFact, Immowelt Sync.' },
{ id: 'calendar', label: 'Termine / Booking', desc: 'Calendly, Shore, Doctolib etc.' },
{ id: 'social', label: 'Social Media Sync', desc: 'Automatisierte Posts oder Feeds.' },
{ id: 'maps', label: 'Google Maps / Places', desc: 'Standortsuche und Kartenintegration.' },
{ id: 'analytics', label: 'Custom Analytics', desc: 'Anbindung an spezialisierte Tracking-Tools.' },
{
id: "crm",
label: "CRM System",
desc: "HubSpot, Salesforce, Pipedrive etc.",
},
{
id: "erp",
label: "ERP / Warenwirtschaft",
desc: "SAP, Microsoft Dynamics, Xentral etc.",
},
{
id: "stripe",
label: "Stripe / Payment",
desc: "Zahlungsabwicklung und Abonnements.",
},
{
id: "newsletter",
label: "Newsletter / Marketing",
desc: "Mailchimp, Brevo, ActiveCampaign etc.",
},
{
id: "ecommerce",
label: "E-Commerce / Shop",
desc: "Shopify, WooCommerce, Shopware Sync.",
},
{
id: "hr",
label: "HR / Recruiting",
desc: "Personio, Workday, Recruitee etc.",
},
{
id: "realestate",
label: "Immobilien",
desc: "OpenImmo, FlowFact, Immowelt Sync.",
},
{
id: "calendar",
label: "Termine / Booking",
desc: "Calendly, Shore, Doctolib etc.",
},
{
id: "social",
label: "Social Media Sync",
desc: "Automatisierte Posts oder Feeds.",
},
{
id: "maps",
label: "Google Maps / Places",
desc: "Standortsuche und Kartenintegration.",
},
{
id: "analytics",
label: "Custom Analytics",
desc: "Anbindung an spezialisierte Tracking-Tools.",
},
];
export const ASSET_OPTIONS = [
{ id: 'existing_website', label: 'Bestehende Website', desc: 'Inhalte oder Struktur können übernommen werden.' },
{ id: 'logo', label: 'Logo', desc: 'Vektordatei Ihres Logos.' },
{ id: 'styleguide', label: 'Styleguide', desc: 'Farben, Schriften, Design-Vorgaben.' },
{ id: 'content_concept', label: 'Inhalts-Konzept', desc: 'Struktur und Texte sind bereits geplant.' },
{ id: 'media', label: 'Bild/Video-Material', desc: 'Professionelles Bildmaterial vorhanden.' },
{ id: 'icons', label: 'Icons', desc: 'Eigene Icon-Sets vorhanden.' },
{ id: 'illustrations', label: 'Illustrationen', desc: 'Eigene Illustrationen vorhanden.' },
{ id: 'fonts', label: 'Fonts', desc: 'Lizenzen für Hausschriften vorhanden.' },
{
id: "existing_website",
label: "Bestehende Website",
desc: "Inhalte oder Struktur können übernommen werden.",
},
{ id: "logo", label: "Logo", desc: "Vektordatei Ihres Logos." },
{
id: "styleguide",
label: "Styleguide",
desc: "Farben, Schriften, Design-Vorgaben.",
},
{
id: "content_concept",
label: "Inhalts-Konzept",
desc: "Struktur und Texte sind bereits geplant.",
},
{
id: "media",
label: "Bild/Video-Material",
desc: "Professionelles Bildmaterial vorhanden.",
},
{ id: "icons", label: "Icons", desc: "Eigene Icon-Sets vorhanden." },
{
id: "illustrations",
label: "Illustrationen",
desc: "Eigene Illustrationen vorhanden.",
},
{
id: "fonts",
label: "Fonts",
desc: "Lizenzen für Hausschriften vorhanden.",
},
];
export const DESIGN_OPTIONS = [
{ id: 'minimal', label: 'Minimalistisch', desc: 'Viel Weißraum, klare Typografie.' },
{ id: 'bold', label: 'Mutig & Laut', desc: 'Starke Kontraste, große Schriften.' },
{ id: 'nature', label: 'Natürlich', desc: 'Sanfte Erdtöne, organische Formen.' },
{ id: 'tech', label: 'Technisch', desc: 'Präzise Linien, dunkle Akzente.' },
{
id: "minimal",
label: "Minimalistisch",
desc: "Viel Weißraum, klare Typografie.",
},
{
id: "bold",
label: "Mutig & Laut",
desc: "Starke Kontraste, große Schriften.",
},
{
id: "nature",
label: "Natürlich",
desc: "Sanfte Erdtöne, organische Formen.",
},
{ id: "tech", label: "Technisch", desc: "Präzise Linien, dunkle Akzente." },
];
export const EMPLOYEE_OPTIONS = [
{ id: '1-5', label: '1-5 Mitarbeiter' },
{ id: '6-20', label: '6-20 Mitarbeiter' },
{ id: '21-100', label: '21-100 Mitarbeiter' },
{ id: '100+', label: '100+ Mitarbeiter' },
{ id: "1-5", label: "1-5 Mitarbeiter" },
{ id: "6-20", label: "6-20 Mitarbeiter" },
{ id: "21-100", label: "21-100 Mitarbeiter" },
{ id: "100+", label: "100+ Mitarbeiter" },
];
export const SOCIAL_MEDIA_OPTIONS = [
{ id: 'instagram', label: 'Instagram' },
{ id: 'linkedin', label: 'LinkedIn' },
{ id: 'facebook', label: 'Facebook' },
{ id: 'twitter', label: 'Twitter / X' },
{ id: 'tiktok', label: 'TikTok' },
{ id: 'youtube', label: 'YouTube' },
{ id: "instagram", label: "Instagram" },
{ id: "linkedin", label: "LinkedIn" },
{ id: "facebook", label: "Facebook" },
{ id: "twitter", label: "Twitter / X" },
{ id: "tiktok", label: "TikTok" },
{ id: "youtube", label: "YouTube" },
];
export const VIBE_LABELS: Record<string, string> = {
minimal: 'Minimalistisch',
bold: 'Mutig & Laut',
nature: 'Natürlich',
tech: 'Technisch'
minimal: "Minimalistisch",
bold: "Mutig & Laut",
nature: "Natürlich",
tech: "Technisch",
};
export const DEADLINE_LABELS: Record<string, string> = {
asap: 'So schnell wie möglich',
'2-3-months': 'In 2-3 Monaten',
'3-6-months': 'In 3-6 Monaten',
flexible: 'Flexibel'
asap: "So schnell wie möglich",
"2-3-months": "In 2-3 Monaten",
"3-6-months": "In 3-6 Monaten",
flexible: "Flexibel",
};
export const ASSET_LABELS: Record<string, string> = {
existing_website: 'Bestehende Website',
logo: 'Logo',
styleguide: 'Styleguide',
content_concept: 'Inhalts-Konzept',
media: 'Bild/Video-Material',
icons: 'Icons',
illustrations: 'Illustrationen',
fonts: 'Fonts'
existing_website: "Bestehende Website",
logo: "Logo",
styleguide: "Styleguide",
content_concept: "Inhalts-Konzept",
media: "Bild/Video-Material",
icons: "Icons",
illustrations: "Illustrationen",
fonts: "Fonts",
};
export const FEATURE_LABELS: Record<string, string> = {
blog_news: 'Blog / News',
products: 'Produktbereich',
jobs: 'Karriere / Jobs',
refs: 'Referenzen / Cases',
events: 'Events / Termine'
blog_news: "Blog / News",
products: "Produktbereich",
jobs: "Karriere / Jobs",
refs: "Referenzen / Cases",
events: "Events / Termine",
};
export const FUNCTION_LABELS: Record<string, string> = {
search: 'Suche',
filter: 'Filter-Systeme',
pdf: 'PDF-Export',
forms: 'Individuelle Formular-Logik',
members: 'Mitgliederbereich',
calendar: 'Event-Kalender',
multilang: 'Mehrsprachigkeit',
chat: 'Echtzeit-Chat'
search: "Suche",
filter: "Filter-Systeme",
pdf: "PDF-Export",
forms: "Individuelle Formular-Logik",
members: "Mitgliederbereich",
calendar: "Event-Kalender",
multilang: "Mehrsprachigkeit",
chat: "Echtzeit-Chat",
};
export const API_LABELS: Record<string, string> = {
crm_erp: 'CRM / ERP',
payment: 'Payment',
marketing: 'Marketing',
ecommerce: 'E-Commerce',
maps: 'Google Maps / Places',
social: 'Social Media Sync',
analytics: 'Custom Analytics'
crm_erp: "CRM / ERP",
payment: "Payment",
marketing: "Marketing",
ecommerce: "E-Commerce",
maps: "Google Maps / Places",
social: "Social Media Sync",
analytics: "Custom Analytics",
};
export const SOCIAL_LABELS: Record<string, string> = {
instagram: 'Instagram',
linkedin: 'LinkedIn',
facebook: 'Facebook',
twitter: 'Twitter / X',
tiktok: 'TikTok',
youtube: 'YouTube'
instagram: "Instagram",
linkedin: "LinkedIn",
facebook: "Facebook",
twitter: "Twitter / X",
tiktok: "TikTok",
youtube: "YouTube",
};
export const PAGE_LABELS: Record<string, string> = {
Home: 'Startseite',
About: 'Über uns',
Services: 'Leistungen',
Contact: 'Kontakt',
Landing: 'Landingpage',
Legal: 'Impressum & Datenschutz'
Home: "Startseite",
About: "Über uns",
Services: "Leistungen",
Contact: "Kontakt",
Landing: "Landingpage",
Legal: "Impressum & Datenschutz",
};