From 2cb54d4ed4c5a14c06a605dde5b2e0ec0a87cee4 Mon Sep 17 00:00:00 2001 From: neodk2004 Date: Tue, 25 Aug 2026 18:22:58 +0200 Subject: [PATCH] feat(design): rebuild landing page, header, and legal pages against new DESIGN.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces PRODUCT.md/DESIGN.md (Impeccable skill) capturing PawFeed's existing brand identity ("The Spotlight Porch") as durable reference, then applies it: - Landing hero: restrained "spotlight" glow instead of a full orange gradient panel, tagline as the actual headline with a marigold accent on "Stars"/"stars", real PawPrint mark fixed (was a mismatched hand-drawn shape, also fixed a viewBox overflow clipping bug). - Features section: one dominant mechanism (pet-as-identity) plus a quiet supporting list, replacing the four-identical-cards grid craft-floor refuses. - Header: dropped the generic glass-blur sticky nav for a flat header with a soft marigold gradient hairline; CTA button now matches DESIGN.md (rounded-lg, no shadow, same orange as the hero CTA); logo gets a paw-spring hover as a small on-brand moment; new active-page indicator (LandingNavLinks) under the current nav link. - Legal pages (Impressum/Datenschutz/Nutzungsbedingungen): replaced the stacked numbered-card-per-section layout with a flowing typographic document (hairline dividers, no boxes, no arbitrary section-number badges) via the shared LegalLayout/LegalSection components. - Nutzungsbedingungen: moved Sponsoring earlier (now 3a, right after Nutzerinhalte & Urheberrecht) while keeping Salvatorische Klausel/Kontakt last; existing section numbers left untouched to avoid breaking the "gemäß Abschnitt 5" cross-reference in Haftungsausschluss. --- ...8-24-story-reactions-insights-dashboard.md | 91 ++++++++ DESIGN.md | 207 ++++++++++++++++++ PRODUCT.md | 66 ++++++ messages/de.json | 2 +- messages/en.json | 2 +- src/app/datenschutz/page.tsx | 2 +- src/app/globals.css | 49 +++++ src/app/impressum/page.tsx | 2 +- src/app/nutzungsbedingungen/page.tsx | 62 +++--- src/app/page.tsx | 201 +++++++++-------- src/components/landing/LandingHeader.tsx | 22 +- src/components/landing/LandingNavLinks.tsx | 42 ++++ src/components/legal/LegalLayout.tsx | 48 ++-- 13 files changed, 640 insertions(+), 156 deletions(-) create mode 100644 .claude/handoffs/2026-08-24-story-reactions-insights-dashboard.md create mode 100644 DESIGN.md create mode 100644 PRODUCT.md create mode 100644 src/components/landing/LandingNavLinks.tsx diff --git a/.claude/handoffs/2026-08-24-story-reactions-insights-dashboard.md b/.claude/handoffs/2026-08-24-story-reactions-insights-dashboard.md new file mode 100644 index 0000000..0d8513c --- /dev/null +++ b/.claude/handoffs/2026-08-24-story-reactions-insights-dashboard.md @@ -0,0 +1,91 @@ +# Session Handoff: Story Reactions/Comments (#29) + Pet Insights Dashboard (#30) + +**Date:** 2026-08-24 +**Project:** T:\CC-Projekte\OnlyPets (PawFeed) +**Session Duration:** ~4 hours + +## Current State + +**Task:** Implement Gitea #29 (paw reactions + comments for Stories) and #30 (owner-facing post/story analytics dashboard, explicitly built on top of #29), then a same-session follow-up making the dashboard's spotlight items clickable. +**Phase:** Complete +**Progress:** 100% — both features implemented, tested, committed, deployed live, and both Gitea issues closed. + +## What We Did + +Read Gitea #29 ("Story Erweiterung"): comments-as-overlay-on-the-running-video + a paw-like button for Stories. Implemented `StoryReaction`/`StoryComment` Prisma models (mirroring `Reaction`/`Comment` and `AdReaction`/`AdComment`), new `stories.toggleReaction`/`listComments`/`addComment`/`deleteComment` procedures, and two new client components (`StoryPawButton`, `StoryCommentsOverlay`) wired into `StoryViewer.tsx`. Committed + user asked to defer deploy. + +Read Gitea #30 ("Nutzer Daten erweitern", explicitly blocked on #29 per its own comment): a small per-pet analytics tool under "Meine Tiere" showing liked posts/stories and which post/story has the most comments. Built a new `insights` tRPC router (`getPetInsights`) aggregating the reaction/comment counters from both #29 and the pre-existing Post counters, plus a new `/pets/[petId]/insights` page + `InsightsDashboard` component reachable via a new "Statistik" link on the owner's own pet profile. Committed, then user asked to commit+deploy both #29 and #30 together, comment on both issues, and deploy — done. + +Follow-up in the same session: user asked for the dashboard's "most liked/commented post/story" cards to be directly clickable. Made `SpotlightCard` a real button; clicking a post opens the existing `PostDetailDialog` (same fetch-by-id pattern as the notifications page); clicking a story opens `StoryViewer` with a new `initialStoryId` prop that jumps straight to that story instead of always starting at index 0. Committed + deployed. + +Commented on both issues with what shipped + commit hashes, then closed both #29 and #30 at the user's request. + +## Decisions Made + +- **StoryReaction/StoryComment as separate models, not a polymorphic postId/storyId table** — matches this codebase's existing precedent (Post↔Reaction/Comment vs. Advertisement↔AdReaction/AdComment are already two separate parallel model families, not unified). +- **No notification wiring for story reactions/comments** — Notification has no `storyId` FK and stories expire in 24h, so a notification deep-linking to expired content would point at nothing. Matches the Advertisement engagement model, which also has zero `notify()` calls despite having reactions/comments/reposts. +- **Comment overlay does NOT pause the story** — the issue's own wording was "Overlay zum laufenden Video" (overlay on the *running* video), so `StoryCommentsOverlay` is a translucent `bg-black/40` panel on top, story keeps playing/advancing underneath. +- **`StoryPawButton`'s `initialReacted` is always `false`** — deliberately mirrors `PawButton.tsx`'s existing, documented limitation (no per-viewer reaction state in `listActive`) rather than adding a new query just for Stories. +- **New `insights` router, not extending the existing `stats` router** — `stats.ts` is an unrelated public/unauthenticated "Über uns" counters router (owner/pet/sponsor totals), not per-pet analytics. +- **Insights scopes stories to `expiresAt > now`** — an expired story's media isn't viewable anywhere else in the app, so surfacing it as "your top story" would point at dead content. +- **Insights filters posts to `hiddenAt: null`** — consistent with every other reader-facing query in the app (feed/explore/profile/search). +- **i18n: singular/plural key pairs, not ICU `{count, plural, ...}` syntax** — matches the project's existing convention (`Comments.countSingular`/`countPlural`, `StoryViewer.sheetTitleSingular`/`Plural`), not a project-wide standard I introduced. +- **Deploy files via `cat local | ssh daniel@192.168.1.222 "cat > 'remote/path'"` per file, not `git pull` on the server** — confirmed this session that any `git` subcommand run over SSH on the NAS gets blocked by the local Claude Code auto-mode classifier (tried `git status`, `git rev-parse HEAD`), even though a July 2026 memory says the server has its own git clone that could in theory `git pull`. The `cat|ssh` + `./rolling-deploy.sh` loop from the prior session's handoff is what actually worked today — treat that as the current source of truth over the older memory. + +## Code Changes + +**#29 — Story reactions/comments (commit `05c9abf`):** +- `prisma/schema.prisma` — new `StoryReaction`/`StoryComment` models, `Story.reactionCount`/`commentCount` counters, new `Pet.storyReactions`/`storyComments` back-relations. Applied via `prisma db push` (never `migrate`, shared dev/prod DB). +- `src/trpc/routers/stories.ts` — `toggleReaction`, `listComments`, `addComment`, `deleteComment` (ownership + block checks, rate-limited, reject on expired stories). +- `src/components/stories/StoryPawButton.tsx` (new), `src/components/stories/StoryCommentsOverlay.tsx` (new), `src/components/stories/StoryViewer.tsx` (wired both in, bottom-right button stack). +- `src/__tests__/stories.test.ts` (+8 tests), `src/__tests__/helpers/prisma-mock.ts` (added `storyReaction`/`storyComment` mocks). +- `messages/en.json`/`de.json` — `StoryViewer.openComments`. + +**#30 — Insights dashboard (commit `4544857`):** +- `src/trpc/routers/insights.ts` (new) — `getPetInsights({petId})`, owner-only, 6 parallel Prisma queries (2×`aggregate`, 4×`findFirst`). +- `src/trpc/routers/_app.ts` — registered `insights: insightsRouter`. +- `src/app/(app)/pets/[petId]/insights/page.tsx` (new) — owner-only gate, mirrors `health/page.tsx`. +- `src/components/insights/InsightsDashboard.tsx` (new) — stat tiles + spotlight cards for posts/stories. +- `src/app/(app)/pets/[petId]/page.tsx` — new "Statistik"/"Insights" link next to Edit/Health. +- `src/__tests__/insights.test.ts` (new, 4 tests), `prisma-mock.ts` (added `aggregate`/`findFirst` to post/story mocks). +- `messages/en.json`/`de.json` — new `Insights` namespace, `PetProfile.insights`. + +**Follow-up — clickable spotlight (commit `6e9e08b`):** +- `src/components/stories/StoryViewer.tsx` — new optional `initialStoryId` prop; open-reset effect now jumps to that story's index (falls back to 0 if not found/omitted). +- `src/components/insights/InsightsDashboard.tsx` — `SpotlightCard` is now a `