diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..2c4112f37 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Bulk reformats. `git config blame.ignoreRevsFile .git-blame-ignore-revs` +68dc0914d70d63eec885d513faf9ae80c35a8ec9 # prettier + CSS comment fix diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index a6dd73d1f..fd4b2eeb0 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -4,4 +4,4 @@ # options. We do not run a GitHub Sponsors / Patreon / Ko-fi page — # we're a Swiss Verein, not an individual maintainer. -custom: ["https://revamp-it.ch/get-involved/donate"] +custom: ['https://revamp-it.ch/get-involved/donate'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 806b270de..9f136b607 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: 🐛 Bug Report description: Create a report to help us fix a bug -title: "[Bug]: " -labels: ["bug", "needs-triage"] +title: '[Bug]: ' +labels: ['bug', 'needs-triage'] body: - type: markdown attributes: @@ -84,4 +84,4 @@ body: attributes: label: Additional Context description: Add any other context about the problem here - placeholder: Any additional information that might help us understand the issue \ No newline at end of file + placeholder: Any additional information that might help us understand the issue diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 906d66cd3..601826364 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,7 +1,7 @@ name: ✨ Feature Request description: Suggest an idea for RevampIT -title: "[Feature]: " -labels: ["enhancement", "needs-triage"] +title: '[Feature]: ' +labels: ['enhancement', 'needs-triage'] body: - type: markdown attributes: @@ -74,4 +74,4 @@ body: options: - label: I'd be willing to implement this feature myself - label: I'd be willing to help with testing - - label: I'd be willing to help with documentation \ No newline at end of file + - label: I'd be willing to help with documentation diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 54fe8c06e..b88f072c7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,76 +1,76 @@ version: 2 updates: # JavaScript/TypeScript dependencies (npm) - - package-ecosystem: "npm" - directory: "/" + - package-ecosystem: 'npm' + directory: '/' schedule: - interval: "weekly" - day: "monday" + interval: 'weekly' + day: 'monday' open-pull-requests-limit: 10 # tiptap's packages share one version and break TypeScript's command # augmentation when bumped separately — they must move as one PR. groups: tiptap: patterns: - - "@tiptap/*" + - '@tiptap/*' # react-dom and the @types packages peer-pin react's major — a half-bump # (react without react-dom, or code types split) cannot even npm ci. react: patterns: - - "react" - - "react-dom" - - "@types/react" - - "@types/react-dom" + - 'react' + - 'react-dom' + - '@types/react' + - '@types/react-dom' # eslint-config-next is version-locked to next; a half-bump breaks lint. next: patterns: - - "next" - - "eslint-config-next" + - 'next' + - 'eslint-config-next' # @auth/pg-adapter peer-depends on next-auth — the pair that produced the # 2026-08 advisories must move together or neither installs. next-auth: patterns: - - "next-auth" - - "@auth/*" + - 'next-auth' + - '@auth/*' # Tailwind v4 splits the engine from the PostCSS plugin; they share a # version and a config format. tailwind: patterns: - - "tailwindcss" - - "@tailwindcss/*" - - "postcss" + - 'tailwindcss' + - '@tailwindcss/*' + - 'postcss' eslint: patterns: - - "eslint" - - "@eslint/*" - - "eslint-plugin-*" + - 'eslint' + - '@eslint/*' + - 'eslint-plugin-*' jest: patterns: - - "jest" - - "jest-environment-*" - - "@types/jest" - - "@testing-library/*" + - 'jest' + - 'jest-environment-*' + - '@types/jest' + - '@testing-library/*' ignore: # @types/node must track the RUNTIME major, not the newest release. CI # (ci.yml NODE_VERSION) and the self-host deploy both pin Node 20, so a # major bump types APIs production does not have — it also fails `verify`. # Raise this deliberately when the runtime moves. (PR #356 closed for this.) - - dependency-name: "@types/node" - update-types: ["version-update:semver-major"] + - dependency-name: '@types/node' + update-types: ['version-update:semver-major'] commit-message: - prefix: "deps" + prefix: 'deps' labels: - - "dependencies" - - "security" + - 'dependencies' + - 'security' # GitHub Actions - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: 'github-actions' + directory: '/' schedule: - interval: "weekly" - day: "monday" + interval: 'weekly' + day: 'monday' commit-message: - prefix: "ci" + prefix: 'ci' labels: - - "ci" - - "dependencies" + - 'ci' + - 'dependencies' diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..b6986633c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,31 @@ +# Build output and vendored trees — formatting these is noise. +node_modules +.next +dist +build +out +coverage +.turbo +.vercel +*.min.js +*.min.css + +# Generated during a build, so it is absent locally and present in CI — which +# makes a clean local --check no evidence at all. Contentlayer's output also +# uses import assertions, which prettier's parser rejects outright. +.contentlayer +.astro +.svelte-kit +storybook-static +test-results +playwright-report + +# Lockfiles are generated; prettier would rewrite them wholesale. +package-lock.json +pnpm-lock.yaml +yarn.lock + +# Markdown is deliberately out of scope for now. Prettier rewraps prose, which +# is where it is most opinionated and least useful, and it would bury the real +# diff. Remove this line when you want docs formatted too. +*.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..616247af0 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2, + "trailingComma": "all", + "arrowParens": "always", + "endOfLine": "lf" +} diff --git a/__mocks__/next-intl.js b/__mocks__/next-intl.js index cd78add93..898bee40f 100644 --- a/__mocks__/next-intl.js +++ b/__mocks__/next-intl.js @@ -7,40 +7,44 @@ * mock this module locally with jest.mock('next-intl', ...). */ -const useTranslations = (_namespace) => (key, _params) => key +const useTranslations = (_namespace) => (key, _params) => key; -const useLocale = () => 'de' +const useLocale = () => 'de'; -const useMessages = () => ({}) +const useMessages = () => ({}); const useFormatter = () => ({ dateTime: (date) => String(date), number: (n) => String(n), relativeTime: (date) => String(date), list: (items) => items.join(', '), -}) +}); -const NextIntlClientProvider = ({ children }) => children +const NextIntlClientProvider = ({ children }) => children; -const getTranslations = async (_namespace) => (key, _params) => key +const getTranslations = async (_namespace) => (key, _params) => key; -const getMessages = async () => ({}) +const getMessages = async () => ({}); -const getLocale = async () => 'de' +const getLocale = async () => 'de'; -const defineRouting = (config) => config +const defineRouting = (config) => config; const createNavigation = (_routing) => { const Link = ({ href, children, className, ...props }) => { - const React = require('react') - return React.createElement('a', { href: typeof href === 'string' ? href : href?.pathname ?? '#', className, ...props }, children) - } - const redirect = jest.fn() - const usePathname = () => '/' - const useRouter = () => ({ push: jest.fn(), replace: jest.fn(), refresh: jest.fn() }) - const getPathname = ({ href }) => (typeof href === 'string' ? href : href?.pathname ?? '/') - return { Link, redirect, usePathname, useRouter, getPathname } -} + const React = require('react'); + return React.createElement( + 'a', + { href: typeof href === 'string' ? href : (href?.pathname ?? '#'), className, ...props }, + children, + ); + }; + const redirect = jest.fn(); + const usePathname = () => '/'; + const useRouter = () => ({ push: jest.fn(), replace: jest.fn(), refresh: jest.fn() }); + const getPathname = ({ href }) => (typeof href === 'string' ? href : (href?.pathname ?? '/')); + return { Link, redirect, usePathname, useRouter, getPathname }; +}; module.exports = { useTranslations, @@ -53,4 +57,4 @@ module.exports = { getLocale, defineRouting, createNavigation, -} +}; diff --git a/deliverables/2026-07-13-kivitendo-intake-ui/handoff.html b/deliverables/2026-07-13-kivitendo-intake-ui/handoff.html index bfc7d6efa..b3bef35cb 100644 --- a/deliverables/2026-07-13-kivitendo-intake-ui/handoff.html +++ b/deliverables/2026-07-13-kivitendo-intake-ui/handoff.html @@ -1,187 +1,545 @@ @@ -189,9 +547,11 @@

Übergabe · Revamp-IT

Kivitendo Auftragserfassung, tablet-tauglich

-

Ein reines Aussehen-Update für die Verkaufsauftrags-Maske: grössere Schrift, - ruhigere Kontraste, Touch-Ziele ab 44 px und eine Positions-Tabelle, die auf dem Tablet - scrollt statt abzuschneiden. Die Kivitendo-Struktur bleibt unangetastet.

+

+ Ein reines Aussehen-Update für die Verkaufsauftrags-Maske: grössere Schrift, ruhigere + Kontraste, Touch-Ziele ab 44 px und eine Positions-Tabelle, die auf dem Tablet scrollt + statt abzuschneiden. Die Kivitendo-Struktur bleibt unangetastet. +

CSS-only Update-sicher @@ -210,17 +570,26 @@

Kivitendo Auftragserfassung, tablet-tauglich

ANSEHEN

Die Live-Vorschau

-

Direkt hier unten — das Ziel-Aussehen, umschaltbar zwischen Desktop und Tablet. Nichts installieren.

+

+ Direkt hier unten — das Ziel-Aussehen, umschaltbar zwischen Desktop und Tablet. Nichts + installieren. +

EINBINDEN

Ein Stylesheet

-

Eine eigene .css nach der main.css laden. Kein Eingriff in Kivitendo, überlebt Updates.

+

+ Eine eigene .css nach der main.css laden. Kein Eingriff in + Kivitendo, überlebt Updates. +

PRÜFEN

2 Minuten mit F12

-

Ich sehe eure Live-DOM nicht. Alle unsicheren Selektoren sind mit ⚠ PRÜFEN markiert.

+

+ Ich sehe eure Live-DOM nicht. Alle unsicheren Selektoren sind mit + ⚠ PRÜFEN markiert. +

@@ -230,7 +599,10 @@

2 Minuten mit F12

02

Live-Vorschau

-

Das exakte Ziel-Aussehen. Schalte auf Tablet um — die Kopffelder stapeln, die Positions-Tabelle scrollt waagrecht.

+

+ Das exakte Ziel-Aussehen. Schalte auf Tablet um — die Kopffelder stapeln, die + Positions-Tabelle scrollt waagrecht. +

@@ -244,7 +616,12 @@

Live-Vorschau

- +
@@ -256,7 +633,10 @@

Live-Vorschau

03

Einbinden — update-sicher

-

Nicht in main.css schreiben (wird bei Updates überschrieben). Als eigene Datei laden.

+

+ Nicht in main.css schreiben (wird bei Updates überschrieben). Als eigene + Datei laden. +

    @@ -264,30 +644,43 @@

    Einbinden — update-sicher

    1

    Datei ablegen

    -

    Speichere kivitendo-intake.css unter css/kivitendo/revamp-intake.css (oder einem eigenen Ordner deiner Wahl).

    +

    + Speichere kivitendo-intake.css unter + css/kivitendo/revamp-intake.css (oder einem eigenen Ordner deiner Wahl). +

  1. 2

    Nach der main.css laden

    -

    Im Layout-Template referenzieren — nach der main.css, damit dein Stil gewinnt. So bleibt ein Kivitendo-Update unberührt.

    +

    + Im Layout-Template referenzieren — nach der main.css, + damit dein Stil gewinnt. So bleibt ein Kivitendo-Update unberührt. +

  2. 3

    Öffnen & kurz prüfen

    -

    Auftragsmaske öffnen. Passt alles, bist du fertig. Greift ein Block nicht: F12 → echten Klassen-/ID-Namen ablesen → im CSS ersetzen.

    +

    + Auftragsmaske öffnen. Passt alles, bist du fertig. Greift ein Block nicht: F12 → echten + Klassen-/ID-Namen ablesen → im CSS ersetzen. +

-

Die Positions-Tabelle #row_table_id füllt Kivitendo — an der Struktur ändern wir nichts. - Das CSS stylt sie nur um: grössere Zellen, fixierte Kopfzeile beim Scrollen, Zeilenstreifen, rechtsbündige Zahlen, - waagrechtes Scrollen auf dem Tablet. Diese ID ist bestätigt; die übrigen mit ⚠ PRÜFEN markierten - Selektoren (Kopf-Wrapper, Summen-Container, Zahlen-Klasse) sind sichere Annahmen für 3.9.x — bei Bedarf mit F12 gegenprüfen.

+

+ Die Positions-Tabelle #row_table_id füllt Kivitendo — an der + Struktur ändern wir nichts. Das CSS stylt sie nur um: grössere Zellen, fixierte Kopfzeile + beim Scrollen, Zeilenstreifen, rechtsbündige Zahlen, waagrechtes Scrollen auf dem Tablet. + Diese ID ist bestätigt; die übrigen mit ⚠ PRÜFEN markierten Selektoren + (Kopf-Wrapper, Summen-Container, Zahlen-Klasse) sind sichere Annahmen für 3.9.x — bei Bedarf + mit F12 gegenprüfen. +

@@ -315,23 +708,41 @@

Das CSS zum Kopieren

05

Feintuning

-

Ganz oben im CSS gibt es einen :root-Block mit Stellschrauben.

+

+ Ganz oben im CSS gibt es einen :root-Block + mit Stellschrauben. +

-
--ri-text: 17pxBasis-Schriftgrösse. Älteren Augen zuliebe hochsetzen.
-
--ri-text-lg: 19pxBeschriftungen & wichtige Felder.
-
--ri-accent: #0b6b5fRevamp-Grün für Fokus & Primäraktion.
-
--ri-touch: 44pxMindest-Touchfläche fürs Tablet.
-
body.ri-xlKlasse am <body> setzen → +2px überall.
-
--ri-radius: 8pxEcken-Rundung von Feldern & Buttons.
+
+ --ri-text: 17pxBasis-Schriftgrösse. Älteren Augen zuliebe hochsetzen. +
+
+ --ri-text-lg: 19pxBeschriftungen & wichtige Felder. +
+
+ --ri-accent: #0b6b5fRevamp-Grün für Fokus & Primäraktion. +
+
+ --ri-touch: 44pxMindest-Touchfläche fürs Tablet. +
+
+ body.ri-xlKlasse am <body> setzen → +2px überall. +
+
+ --ri-radius: 8pxEcken-Rundung von Feldern & Buttons. +