diff --git a/frontend/app/globals.css b/frontend/app/globals.css index 100628a..d07cd68 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css @@ -45,12 +45,7 @@ html, body { -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} + body { background: var(--background); @@ -129,22 +124,7 @@ body { transform: translateY(0); } } -.postcard { - background: var(--color-surface); - border-radius: var(--radius-lg); - border: 1px solid var(--color-border); - box-shadow: var(--shadow-sm); - padding: var(--space-md); - display: flex; - flex-direction: column; - gap: var(--space-sm); - transition: box-shadow 0.2s ease, transform 0.2s ease; -} -.postcard:hover { - box-shadow: var(--shadow-md); - transform: translateY(-1px); -} .postcard { background: var(--color-surface); border-radius: var(--radius-lg); @@ -187,7 +167,7 @@ body { .postcard--discovery { border: 1px solid var(--color-primary); box-shadow: - 0 0 0 1px rgba(46, 125, 50, 0.15), + 0 0 0 1px rgba(236, 214, 15, 0.925), var(--shadow-sm); } .feed-header, @@ -204,7 +184,7 @@ body { display: flex; flex-direction: column; gap: var(--space-md); - padding: 0 var(--space-md) var(--space-xl); + padding-bottom: calc(var(--space-xl) + 60px); } .fresh-scroll, .trending-scroll { @@ -214,9 +194,7 @@ body { padding: var(--space-sm) var(--space-md); } -.hide-scrollbar { - scrollbar-width: none; -} + .hide-scrollbar::-webkit-scrollbar { display: none; @@ -238,16 +216,43 @@ body { display: flex; gap: var(--space-lg); padding: var(--space-lg); + margin: var(--space-md); background: var(--color-surface); border-radius: var(--radius-lg); border: 1px solid var(--color-border); box-shadow: var(--shadow-sm); - margin: var(--space-md); } +.profile-avatar { + width: 72px; + height: 72px; + border-radius: 50%; + background: var(--color-primary-soft); + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; +} +.profile-info h1 { + font-size: 1.3rem; + margin: 0; +} + +.profile-username { + font-size: 0.85rem; + color: var(--color-text-muted); +} + +.profile-bio { + margin-top: var(--space-sm); + font-size: 0.9rem; + color: var(--color-text-secondary); +} + + .profile-stats { display: flex; gap: var(--space-lg); - margin-top: var(--space-sm); + margin-top: var(--space-md); } .profile-stats div { @@ -255,13 +260,51 @@ body { } .profile-stats strong { - font-size: 1.1rem; + font-size: 1.05rem; + font-weight: 600; } .profile-stats span { - font-size: 0.8rem; + font-size: 0.75rem; color: var(--color-text-muted); } +.profile-pets { + margin-top: var(--space-lg); + padding: 0 var(--space-md); +} + +.profile-pets h2 { + font-size: 1.1rem; + margin-bottom: var(--space-sm); +} +.pets-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + gap: var(--space-md); +} +.pet-card { + background: var(--color-surface); + border-radius: var(--radius-md); + border: 1px solid var(--color-border); + box-shadow: var(--shadow-sm); + padding: var(--space-sm); + text-align: center; + transition: box-shadow 0.2s ease, transform 0.2s ease; +} +.profile-posts { + margin-top: var(--space-xl); +} + +.profile-posts h2 { + font-size: 1.1rem; + margin: 0 var(--space-md) var(--space-sm); +} + +.pet-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-1px); +} + .post-preview-overlay { position: fixed; inset: 0; @@ -270,13 +313,328 @@ body { justify-content: center; align-items: flex-end; z-index: 50; + overflow: hidden; } .post-preview-modal { background: var(--color-surface); width: 100%; max-width: 600px; + + /* 🔥 DAS FEHLT */ + max-height: calc(100vh - 70px); /* Platz für Statusbar */ + overflow-y: auto; + border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding: var(--space-lg); box-shadow: var(--shadow-lg); + padding-bottom: calc(var(--space-xl) + 60px); +} + +.explore-filter { + display: flex; + gap: var(--space-sm); + margin-top: var(--space-md); +} + +.filter-button { + padding: 0.4rem 0.8rem; + border-radius: 999px; + border: 1px solid var(--color-border); + background: var(--color-surface); + font-size: 0.85rem; + color: var(--color-text-secondary); + cursor: pointer; +} + +.filter-button.active { + background: var(--color-primary); + color: white; + border-color: var(--color-primary); +} + +.explore-header, +.explore-trending, +.explore-posts { + padding: 0 var(--space-md); +} + +.explore-trending, +.explore-posts { + margin-top: var(--space-lg); +} +.explore-header h1 { + font-size: 1.4rem; + margin-bottom: 0.2rem; +} + +.explore-header p { + font-size: 0.9rem; + color: var(--color-text-secondary); +} + +.explore-trending strong, +.explore-posts strong { + display: block; + margin-bottom: var(--space-sm); +} +.feed-header { + padding: var(--space-lg) var(--space-md) var(--space-md); +} + +.feed-header h1 { + font-size: 1.4rem; + margin-bottom: 0.2rem; +} + +.feed-header p { + font-size: 0.9rem; + color: var(--color-text-secondary); +} +.feed-posts { + margin-top: var(--space-md); +} +.feed-posts .postcard { + margin-bottom: var(--space-md); +} +.feed-header h1::after { + content: '•'; + margin-left: 0.4rem; + color: var(--color-primary); +} +.pets-page { + padding-bottom: calc(var(--space-xl) + 60px); /* Abstand zur BottomNav */ +} +.pets-header { + padding: var(--space-lg) var(--space-md) var(--space-md); +} + +.pets-header h1 { + font-size: 1.4rem; + margin-bottom: 0.25rem; +} + +.pets-header p { + font-size: 0.9rem; + color: var(--color-text-secondary); + margin: 0; +} +.pets-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); + gap: var(--space-md); + padding: 0 var(--space-md); +} +.pet-card { + background: var(--color-surface); + border-radius: var(--radius-lg); + border: 1px solid var(--color-border); + box-shadow: var(--shadow-sm); + padding: var(--space-md); + text-align: center; + text-decoration: none; + color: inherit; + display: flex; + flex-direction: column; + gap: 0.3rem; + transition: box-shadow 0.2s ease, transform 0.2s ease; +} + +.pet-card:hover { + box-shadow: var(--shadow-md); + transform: translateY(-1px); +} +.pet-avatar { + width: 56px; + height: 56px; + border-radius: 50%; + background: var(--color-primary-soft); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.6rem; + margin: 0 auto var(--space-sm); +} +.pet-name { + font-size: 1rem; + font-weight: 600; +} + +.pet-meta { + font-size: 0.8rem; + color: var(--color-text-muted); +} + +.pet-age { + font-size: 0.75rem; + color: var(--color-text-secondary); +} +.pets-actions { + margin-top: var(--space-xl); + padding: 0 var(--space-md); +} +.button-primary { + display: inline-flex; + justify-content: center; + align-items: center; + gap: 0.4rem; + padding: 0.8rem 1.2rem; + border-radius: var(--radius-lg); + background: var(--color-primary); + color: white; + font-weight: 600; + text-decoration: none; + border: none; + cursor: pointer; + box-shadow: var(--shadow-sm); + transition: box-shadow 0.2s ease, transform 0.15s ease; +} + +.button-primary:hover { + box-shadow: var(--shadow-md); + transform: translateY(-1px); +} +.button-secondary { + display: inline-flex; + justify-content: center; + align-items: center; + padding: 0.8rem 1.2rem; + border-radius: var(--radius-lg); + background: var(--color-surface); + color: var(--color-text-main); + border: 1px solid var(--color-border); + font-weight: 500; + cursor: pointer; +} +.button-danger { + background: #c62828; + color: white; + border: none; +} + +.button-danger:hover { + background: #b71c1c; +} +.badge { + display: inline-block; + padding: 0.15rem 0.5rem; + font-size: 0.7rem; + border-radius: 999px; + background: var(--color-border); + color: var(--color-text-muted); +} +.badge-pet { + background: var(--color-primary-soft); + color: var(--color-primary); +} +.postcard--discovery { + border: 1px solid var(--color-primary); + box-shadow: + 0 0 0 1px rgba(46, 125, 50, 0.15), + var(--shadow-sm); +} +.empty-state { + padding: var(--space-xl); + margin: var(--space-md); + text-align: center; + background: var(--color-surface); + border-radius: var(--radius-lg); + border: 1px dashed var(--color-border); + color: var(--color-text-secondary); +} + +.empty-state strong { + display: block; + font-size: 1rem; + font-weight: 600; + color: var(--color-text-main); + margin-bottom: 0.3rem; +} + +.empty-state span { + font-size: 0.85rem; + line-height: 1.4; +} +.empty-state--explore { + border-style: solid; +} +.empty-state--pets { + border-style: dashed; +} + +button:active, +.button-primary:active { + transform: scale(0.98); +} + +a { + -webkit-tap-highlight-color: transparent; +} +section + section { + margin-top: var(--space-xl); +} + +h1, h2, h3 { + line-height: 1.25; +} +.pet-detail-page { + padding-bottom: calc(var(--space-xl) + 60px); /* Platz für BottomNav */ +} +.pet-detail-header { + display: flex; + gap: var(--space-lg); + padding: var(--space-lg); + margin: var(--space-md); + background: var(--color-surface); + border-radius: var(--radius-lg); + border: 1px solid var(--color-border); + box-shadow: var(--shadow-sm); + align-items: center; +} +.pet-detail-avatar { + width: 72px; + height: 72px; + border-radius: 50%; + background: var(--color-primary-soft); + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; + flex-shrink: 0; +} +.pet-detail-info h1 { + font-size: 1.4rem; + margin: 0; +} + +.pet-detail-meta { + display: block; + font-size: 0.9rem; + color: var(--color-text-secondary); + margin-top: 0.2rem; +} + +.pet-detail-owner { + display: block; + font-size: 0.8rem; + color: var(--color-text-muted); + margin-top: 0.3rem; +} +.pet-detail-posts { + margin-top: var(--space-xl); +} + +.pet-detail-posts h2 { + font-size: 1.1rem; + margin: 0 var(--space-md) var(--space-sm); +} + +.container { + max-width: 720px; + margin: 0 auto; +} +.divider { + height: 1px; + background: var(--color-border); + margin: var(--space-lg) 0; } diff --git a/frontend/app/pets/[id]/page.tsx b/frontend/app/pets/[id]/page.tsx index 63ea599..1b9bc50 100644 --- a/frontend/app/pets/[id]/page.tsx +++ b/frontend/app/pets/[id]/page.tsx @@ -1,27 +1,27 @@ +'use client'; + +import { useParams } from 'next/navigation'; import PostCard from '@/app/components/PostCard/PostCard'; -type Comment = { - id: number; - author: string; - text: string; -}; - -type PetPost = { - id: number; - text: string; - createdAt: string; - likes: number; - commentsCount: number; - commentsList: Comment[]; -}; - type Pet = { id: number; name: string; type: 'Hund' | 'Katze'; breed: string; - bio?: string; - posts: PetPost[]; + age?: string; + owner: string; +}; + +type Post = { + id: number; + petId: number; + petName: string; + petType: 'Hund' | 'Katze'; + author: string; + text: string; + createdAt: string; + likes: number; + comments: number; }; const mockPets: Pet[] = [ @@ -29,76 +29,103 @@ const mockPets: Pet[] = [ id: 1, name: 'Luna', type: 'Katze', - breed: 'Bengal x Mix', - bio: 'Neugierig, verspielt und liebt Sonne.', - posts: [ - { - id: 101, - text: 'Luna genießt die Sonne ☀️', - createdAt: 'vor 2 Stunden', - likes: 12, - commentsCount: 2, - commentsList: [ - { id: 1, author: 'Lisa', text: 'Wie süß 😍' }, - { id: 2, author: 'Tom', text: 'Typisch Bengal!' }, - ], - }, - ], + breed: 'Bengal', + age: '2 Jahre', + owner: 'Anna', }, { id: 2, name: 'Bello', type: 'Hund', - breed: 'Labrador Retriever x Mix', - bio: 'Immer gute Laune.', - posts: [], + breed: 'Labrador', + age: '4 Jahre', + owner: 'Markus', }, ]; -type PageProps = { - params: Promise<{ id: string }>; -}; +const mockPosts: Post[] = [ + { + id: 101, + petId: 1, + petName: 'Luna', + petType: 'Katze', + author: 'Anna', + text: 'Luna liebt sonnige Nachmittage auf dem Balkon ☀️', + createdAt: 'vor 3 Stunden', + likes: 12, + comments: 3, + }, + { + id: 102, + petId: 1, + petName: 'Luna', + petType: 'Katze', + author: 'Anna', + text: 'Heute gab es neue Spielsachen 🧶', + createdAt: 'gestern', + likes: 7, + comments: 1, + }, +]; -export default async function PetDetailPage({ params }: PageProps) { - const { id } = await params; // ✅ DAS ist der entscheidende Fix - const petId = Number(id); - - console.log('PET ID:', petId); +export default function PetDetailPage() { + const params = useParams(); + const petId = Number(params.id); const pet = mockPets.find((p) => p.id === petId); + const posts = mockPosts.filter((p) => p.petId === petId); if (!pet) { - return

Haustier nicht gefunden.

; + return ( +
+ Tier nicht gefunden + Dieses Haustier existiert nicht oder wurde entfernt. +
+ ); } return ( -
-
-

{pet.name}

-
{pet.type} ¡ {pet.breed}
- {pet.bio &&

{pet.bio}

} +
+ {/* Header */} +
+
🐾
+ +
+

{pet.name}

+ + + {pet.type} ¡ {pet.breed} + {pet.age && ` ¡ ${pet.age}`} + + + + Betreut von {pet.owner} + +
-
+ {/* Posts */} +

Beiträge

- {pet.posts.length === 0 && ( -

Dieses Haustier hat noch keine Beiträge.

+ {posts.length === 0 ? ( +
+ Noch keine Beiträge + + Fßr {pet.name} wurden noch keine Beiträge erstellt. + +
+ ) : ( +
+ {posts.map((post) => ( + + ))} +
)} - - {pet.posts.map((post) => ( - - ))}
); diff --git a/frontend/app/pets/page.tsx b/frontend/app/pets/page.tsx index 421e909..f02cd42 100644 --- a/frontend/app/pets/page.tsx +++ b/frontend/app/pets/page.tsx @@ -1,75 +1,80 @@ +'use client'; + import Link from 'next/link'; type Pet = { id: number; name: string; type: 'Hund' | 'Katze'; + breed: string; + age?: string; }; const mockPets: Pet[] = [ - { id: 1, name: 'Luna', type: 'Katze' }, - { id: 2, name: 'Bello', type: 'Hund' }, + { + id: 1, + name: 'Luna', + type: 'Katze', + breed: 'Bengal', + age: '2 Jahre', + }, + { + id: 2, + name: 'Bello', + type: 'Hund', + breed: 'Labrador', + age: '4 Jahre', + }, + { + id: 3, + name: 'Milo', + type: 'Katze', + breed: 'Europäisch Kurzhaar', + }, ]; export default function PetsPage() { return ( -
-
-

Meine Haustiere

-

- Verwalte deine Hunde und Katzen +

+ {/* Header */} +
+

Meine Tiere

+

+ Verwalte deine Haustiere – Beiträge sind immer einem Tier zugeordnet.

-
+ {/* Pets Grid */} +
{mockPets.map((pet) => ( -
- {pet.name} -
- {pet.type} -
+
+ 🐾
- › + {pet.name} + + + {pet.type} · {pet.breed} + + + {pet.age && ( + {pet.age} + )} ))} -
+ - - ➕ Haustier hinzufügen - + {/* Add Pet */} +
+ + + Neues Tier hinzufĂźgen + +
); }