diff --git a/Dockerfile b/Dockerfile index 0feb6fb..78eb1a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,12 @@ FROM eclipse-temurin:21-jre +ARG JAR_FILE=target/*.jar + # Zeitzone auf Berlin setzen und 24h-Format konfigurieren ENV TZ=Europe/Berlin ENV LC_TIME=de_DE.UTF-8 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone -COPY target/*.jar app.jar +COPY ${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=production"] diff --git a/UI_GUIDELINES.md b/STYLEGUIDE.md similarity index 90% rename from UI_GUIDELINES.md rename to STYLEGUIDE.md index 1111591..1481a33 100644 --- a/UI_GUIDELINES.md +++ b/STYLEGUIDE.md @@ -2,7 +2,7 @@ > Gilt für alle Views unter `src/main/java/de/assecutor/votianlt/pages/view/` > Theme-Datei: `src/main/frontend/themes/votian-modern/styles.css` -> Stand: UI-Änderungen bis 20.03.2026 berücksichtigt (`ViewToolbar`-Migrationen, Landing-/Dashboard-Updates, TabSheet-Dialoge, Message-/Statistics-Layouts) +> Stand: UI-Änderungen bis 23.03.2026 berücksichtigt (`Landing-Hero-CTA/Demo-Button`, `ViewToolbar`-Migrationen, Landing-/Dashboard-Updates, TabSheet-Dialoge, Message-/Statistics-Layouts) --- @@ -950,6 +950,34 @@ body:has(.landing-view) { } ``` +### Anonymer Header + +- Im anonymen Zustand enthält die Header-Navigation nur `Login`, `Registrieren` und die Sprachwahl. +- Öffentliche Primäraktionen gehören nicht in die Header-Leiste, sondern in das Hero-Panel. +- Der `Demo`-Einstieg wird deshalb nicht als zusätzlicher Header-Button geführt. + +```java +private Component createAnonymousNavigation() { + HorizontalLayout navButtons = new HorizontalLayout(); + navButtons.setSpacing(true); + navButtons.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER); + navButtons.addClassName("landing-nav"); + + Button loginBtn = new Button(getTranslation("start.button.login"), event -> login()); + loginBtn.addThemeVariants(ButtonVariant.LUMO_CONTRAST); + loginBtn.addClassName("landing-nav-button"); + + Button registerBtn = new Button(getTranslation("start.button.register"), event -> register()); + registerBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY); + registerBtn.addClassName("landing-nav-button"); + + Button languageBtn = createLanguageSelector(); + + navButtons.add(loginBtn, registerBtn, languageBtn); + return navButtons; +} +``` + ### App-Section vs. Footer CTA-Text und Slogan liegen auf der Landing Page jetzt im `app-overview-panel`, nicht mehr im Footer. @@ -973,7 +1001,7 @@ CTA-Text und Slogan liegen auf der Landing Page jetzt im `app-overview-panel`, n .hero-panel { position: relative; overflow: hidden; - min-height: 340px; + min-height: 520px; justify-content: center; text-align: center; border-radius: 34px; @@ -991,6 +1019,68 @@ CTA-Text und Slogan liegen auf der Landing Page jetzt im `app-overview-panel`, n color: rgba(226,232,240,0.92); font-size: clamp(1rem, 2vw, 1.15rem); } +.hero-actions { + gap: 1rem; + align-items: center; +} +.hero-action-group { + gap: 0.45rem; + align-items: center; +} +.hero-choice-hint { + max-width: 420px; + margin: 0; + color: rgba(226,232,240,0.82); + font-size: 0.95rem; + line-height: 1.55; + text-align: center; +} +``` + +### Hero-CTA-Regeln + +- Öffentliche CTAs werden in der Hero-Kachel vertikal gestapelt und nicht über Header und Hero verteilt. +- Reihenfolge auf der Landing Page: zuerst `Demo`, danach `Jetzt kostenlos testen`. +- Beide CTA-Buttons verwenden dieselbe Primärdarstellung: `LUMO_PRIMARY`, `LUMO_LARGE`, `setWidthFull()`, Pill-Optik. +- Jeder CTA bekommt direkt darunter einen eigenen Erklärungstext. +- Keine kombinierten Erklärungstexte für mehrere Buttons verwenden; Hinweise immer 1:1 an den jeweiligen CTA binden. + +```java +Button demoButton = new Button(getTranslation("start.button.demo"), event -> loginDemo()); +demoButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_LARGE); +demoButton.addClassNames("hero-cta", "hero-demo-cta"); +demoButton.setWidthFull(); + +Button ctaButton = new Button(getTranslation("cta.freetest"), event -> register()); +ctaButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_LARGE); +ctaButton.addClassName("hero-cta"); +ctaButton.setWidthFull(); + +Paragraph demoHint = new Paragraph(getTranslation("start.hero.demo.hint")); +demoHint.addClassName("hero-choice-hint"); + +Paragraph trialHint = new Paragraph(getTranslation("start.hero.trial.hint")); +trialHint.addClassName("hero-choice-hint"); + +VerticalLayout demoAction = new VerticalLayout(demoButton, demoHint); +demoAction.addClassName("hero-action-group"); + +VerticalLayout trialAction = new VerticalLayout(ctaButton, trialHint); +trialAction.addClassName("hero-action-group"); + +VerticalLayout heroActions = new VerticalLayout(); +heroActions.setPadding(false); +heroActions.setSpacing(false); +heroActions.setWidthFull(); +heroActions.setMaxWidth("420px"); +heroActions.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER); +heroActions.addClassName("hero-actions"); +heroActions.add(demoAction, trialAction); +``` + +```properties +start.hero.demo.hint=Demo startet sofort mit vorbereiteten Beispieldaten. +start.hero.trial.hint="Jetzt kostenlos testen" erstellt Ihren eigenen Account für den kostenlosen Probemonat. ``` --- diff --git a/docker_push.sh b/docker_push.sh index 1ab2a37..822c4a5 100755 --- a/docker_push.sh +++ b/docker_push.sh @@ -1,6 +1,79 @@ -# 1. Login (mit deinen Credentials) -echo "G8m0T3vz" | docker login registry.assecutor.org -u adsg --password-stdin +#!/usr/bin/env bash -# Dann ganz normal pushen -docker buildx build --platform linux/amd64 -t registry.assecutor.org/votianlt:0.9.9 --push . +set -euo pipefail +readonly SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +readonly REGISTRY_IMAGE="registry.assecutor.org/votianlt" + +usage() { + cat <<'EOF' +Verwendung: + ./docker_push.sh [x.y.z] + +Beispiel: + ./docker_push.sh 0.9.13 + ./docker_push.sh + +Voraussetzungen: + - Docker Buildx ist installiert + - Login zur Registry wurde bereits ausgeführt: + docker login registry.assecutor.org + +Ohne Versionsargument wird automatisch die Version aus der pom.xml verwendet. +EOF +} + +fail() { + echo "Fehler: $*" >&2 + exit 1 +} + +require_command() { + command -v "$1" >/dev/null 2>&1 || fail "'$1' wurde nicht gefunden." +} + +resolve_pom_version() { + [[ -x "./mvnw" ]] || fail "'./mvnw' wurde nicht gefunden oder ist nicht ausführbar." + + local version + version="$( + ./mvnw -q -DforceStdout help:evaluate -Dexpression=project.version \ + | awk 'NF { last = $0 } END { print last }' + )" + + [[ -n "${version}" ]] || fail "Version konnte nicht aus der pom.xml ermittelt werden." + echo "${version}" +} + +VERSION="${1:-$(resolve_pom_version)}" + +if [[ "${VERSION}" == "-h" || "${VERSION}" == "--help" ]]; then + usage + exit 0 +fi + +if [[ ! "${VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + fail "Versionsnummer muss das Format x.y.z haben." +fi + +require_command docker +docker buildx version >/dev/null 2>&1 || fail "Docker Buildx ist nicht verfügbar." + +cd "${SCRIPT_DIR}" + +echo "Verwende Release-Version ${VERSION}." +echo "Baue Production-JAR für Version ${VERSION} ..." +./mvnw -Pproduction -DskipTests -Drevision="${VERSION}" package + +JAR_FILE="target/votianlt-${VERSION}.jar" +[[ -f "${JAR_FILE}" ]] || fail "Release-JAR wurde nicht gefunden: ${JAR_FILE}" + +echo "Pushe Image ${REGISTRY_IMAGE}:${VERSION} ..." +docker buildx build \ + --platform linux/amd64 \ + --build-arg "JAR_FILE=${JAR_FILE}" \ + -t "${REGISTRY_IMAGE}:${VERSION}" \ + --push \ + . + +echo "Fertig: ${REGISTRY_IMAGE}:${VERSION}" diff --git a/pom.xml b/pom.xml index a18e51f..4dc4006 100644 --- a/pom.xml +++ b/pom.xml @@ -6,11 +6,12 @@ de.assecutor.votianlt votianlt - 0.9.12 + ${revision} jar + 0.9.12 21 21 21 diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index 6230507..76ac393 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/frontend/themes/votian-modern/styles.css b/src/main/frontend/themes/votian-modern/styles.css index 7cdc5b7..912891a 100644 --- a/src/main/frontend/themes/votian-modern/styles.css +++ b/src/main/frontend/themes/votian-modern/styles.css @@ -361,7 +361,7 @@ vaadin-vertical-layout.admin-form-view { .hero-panel { position: relative; overflow: hidden; - min-height: 420px; + min-height: 520px; justify-content: center; text-align: center; border-radius: 34px;