From a7ce22cc112d9949dc8e53546f73704543939359 Mon Sep 17 00:00:00 2001 From: "Dennis (via Claude+Gemma)" Date: Sat, 23 May 2026 10:48:34 +0200 Subject: [PATCH] feat(price-tag-component): PriceTag mit Currency-Formatting [tsc:fail] --- .phase45-state.json | 3 +- .phase46-state.json | 5 ++ GENERATION_LOG.md | 25 +++++++ apps/web/src/components/PriceTag.tsx | 32 +++++++++ scripts/phase46_features.py | 97 ++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 .phase46-state.json create mode 100644 apps/web/src/components/PriceTag.tsx create mode 100644 scripts/phase46_features.py diff --git a/.phase45-state.json b/.phase45-state.json index 6a00b61..d2509a7 100644 --- a/.phase45-state.json +++ b/.phase45-state.json @@ -5,6 +5,7 @@ "attempted_features": [ "footer-component", "hint-component", - "loader-component" + "loader-component", + "nav-link-component" ] } \ No newline at end of file diff --git a/.phase46-state.json b/.phase46-state.json new file mode 100644 index 0000000..19b8bb5 --- /dev/null +++ b/.phase46-state.json @@ -0,0 +1,5 @@ +{ + "completed_features": [], + "current_feature": "price-tag-component", + "started_at": "2026-05-23T10:48:26.654134" +} \ No newline at end of file diff --git a/GENERATION_LOG.md b/GENERATION_LOG.md index fad37ed..1b089a2 100644 --- a/GENERATION_LOG.md +++ b/GENERATION_LOG.md @@ -4660,3 +4660,28 @@ src/index.ts(27,25): error TS2769: No overload matches this call. Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. Argument of type 'Promise' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. Type 'Promise' provides no match for the signature '(instance: FastifyInstance, +- `10:44:10` **INFO** Committed feature nav-link-component +- `10:44:11` **INFO** Pushed: rc=0 + +## Phase-45 Run beendet (2026-05-23 10:44:11) + +- `10:44:11` **INFO** OK: 0, Attempted: 4, Total: 4 + +## 🚀 Phase-46 Codegen-Run gestartet (2026-05-23 10:48:26) + + +## Phase-3 Feature: price-tag-component (2026-05-23 10:48:26) + +- `10:48:26` **INFO** Description: PriceTag mit Currency-Formatting +- `10:48:26` **INFO** Generating apps/web/src/components/PriceTag.tsx (PriceTag-Component. Props: amountCents (number), currency? (default 'E…) +- `10:48:32` **INFO** wrote 649 chars in 5.6s (attempt 1) +- `10:48:32` **INFO** Running tsc --noEmit on api… +- `10:48:34` **WARN** tsc errors: +src/db/schema.ts(37,14): error TS7022: 'customers' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +src/db/schema.ts(45,59): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +src/db/schema.ts(49,14): error TS7022: 'projects' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer. +src/db/schema.ts(53,56): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +src/index.ts(27,25): error TS2769: No overload matches this call. + Overload 1 of 3, '(plugin: FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...> | undefined): FastifyInstance<...> & PromiseLike<...>', gave the following error. + Argument of type 'Promise' is not assignable to parameter of type 'FastifyPluginCallback<{ limits: { fileSize: number; }; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'. + Type 'Promise' provides no match for the signature '(instance: FastifyInstance, diff --git a/apps/web/src/components/PriceTag.tsx b/apps/web/src/components/PriceTag.tsx new file mode 100644 index 0000000..38fdb3b --- /dev/null +++ b/apps/web/src/components/PriceTag.tsx @@ -0,0 +1,32 @@ +import React from 'react'; + +interface PriceTagProps { + amountCents: number; + currency?: string; + size?: 'sm' | 'md' | 'lg'; +} + +const sizeClasses = { + sm: 'text-xs font-medium', + md: 'text-sm font-semibold', + lg: 'text-base font-bold', +}; + +const PriceTag: React.FC = ({ + amountCents, + currency = 'EUR', + size = 'md' +}) => { + const formattedPrice = new Intl.NumberFormat('de-DE', { + style: 'currency', + currency: currency, + }).format(amountCents / 100); + + return ( + + {formattedPrice} + + ); +}; + +export default PriceTag; \ No newline at end of file diff --git a/scripts/phase46_features.py b/scripts/phase46_features.py new file mode 100644 index 0000000..60ca135 --- /dev/null +++ b/scripts/phase46_features.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +"""Phase-46: standalone components — PriceTag, TimeAgo, Address, IconButton.""" + +from __future__ import annotations + +import asyncio, datetime, json, sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from phase2_features import Feature, FileGen, ROOT, log, log_section +from phase3_features import run_feature_v2 + +PHASE_STATE = ROOT / ".phase46-state.json" + +FEATURES: list[Feature] = [ + Feature( + name="price-tag-component", + description="PriceTag mit Currency-Formatting", + files=[FileGen( + path="apps/web/src/components/PriceTag.tsx", + purpose=( + "PriceTag-Component. Props: amountCents (number), currency? (default 'EUR'), size?: 'sm'|'md'|'lg'. " + "Formatiert via Intl.NumberFormat 'de-DE'. Z.B. 1234 → '12,34 €'. " + "Tailwind. Export default." + ), + )], + ), + Feature( + name="time-ago-component", + description="TimeAgo relative-time (vor X min)", + files=[FileGen( + path="apps/web/src/components/TimeAgo.tsx", + purpose=( + "TimeAgo-Component. Props: date (Date|string). " + "Berechnet diff. Output: 'vor X Sekunden/Minuten/Stunden/Tagen'. " + "Auto-refresh setInterval 60s. Tailwind. Export default." + ), + )], + ), + Feature( + name="address-component", + description="Address für mehrteilige Adressen", + files=[FileGen( + path="apps/web/src/components/Address.tsx", + purpose=( + "Address-Component. Props: street, city, zip, country?. " + "Mehrzeilig: Street / ZIP City / Country. " + "Tailwind. Export default." + ), + )], + ), + Feature( + name="icon-button-component", + description="IconButton (only icon, square, accessible)", + files=[FileGen( + path="apps/web/src/components/IconButton.tsx", + purpose=( + "IconButton-Component. Props: icon (ReactNode), ariaLabel (required), onClick, variant?: 'ghost'|'solid', size?: 'sm'|'md'|'lg'. " + "Square button with focus-ring. aria-label gesetzt. " + "Tailwind. Export default." + ), + )], + ), +] + + +def load_state(): + if PHASE_STATE.exists(): + return json.loads(PHASE_STATE.read_text()) + return {"completed_features": [], "current_feature": None, "started_at": datetime.datetime.now().isoformat()} + + +def save_state(state): + PHASE_STATE.write_text(json.dumps(state, indent=2)) + + +async def main(): + log_section("🚀 Phase-46 Codegen-Run gestartet") + state = load_state() + for feature in FEATURES: + if feature.name in state.get("completed_features", []): + continue + state["current_feature"] = feature.name; save_state(state) + try: + success = await run_feature_v2(feature) + state.setdefault("completed_features" if success else "attempted_features", []).append(feature.name) + save_state(state) + except Exception as e: + log(f"❌ {feature.name} crashed: {e}", level="ERROR") + state.setdefault("attempted_features", []).append(feature.name); save_state(state) + log_section("Phase-46 Run beendet") + log(f"OK: {len(state.get('completed_features', []))}, Attempted: {len(state.get('attempted_features', []))}, Total: {len(FEATURES)}") + return 0 + + +if __name__ == "__main__": + sys.exit(asyncio.run(main()))