Skip to content

Commit 3ccbbda

Browse files
authored
Merge pull request #20 from FakeOverFlow/frontend/wireframe
refactor: redesign Post Details page layout and improve component modularity
2 parents fc9731c + e11068a commit 3ccbbda

16 files changed

Lines changed: 250 additions & 71 deletions

File tree

apps/fakeoverflow-angular/src/app/app.routes.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Routes } from '@angular/router';
22
import { authGuard } from '@guards/auth-guard';
3-
43
export const routes: Routes = [
54
{
65
path: 'auth',
@@ -28,22 +27,26 @@ export const routes: Routes = [
2827
]
2928
},
3029
{ path: 'home', loadComponent: () => import('./pages/home/home/home').then(m => m.Home), },
31-
{
30+
{
3231
path: 'post',
3332
children: [
3433
{
3534
path: 'create',
3635
loadComponent: () => import('./pages/home/home/create-post/post').then(m => m.PostComponent),
3736
canActivate: [authGuard],
3837
title: 'Create Post | FakeOverflow'
38+
},
39+
{
40+
path: ":id",
41+
loadComponent: () => import('./pages/home/home/details/details').then(m => m.DetailsComponent),
42+
title: 'Post | FakeOverflow'
3943
}
40-
]
44+
]
4145
},
4246
{ path: 'update', loadComponent: () => import('./pages/home/home/UpdatePost/update').then(m => m.UpdateComponent) },
43-
{ path: 'detail', loadComponent: () => import('./pages/home/home/PostDetails/details').then(m => m.DetailsComponent) },
47+
{ path: 'detail', loadComponent: () => import('@pages/home/home/details/details').then(m => m.DetailsComponent) },
4448
{ path: 'personalhome', loadComponent: () => import('./pages/home/home/PersonalQuestionsHome/personalHome').then(m => m.PersonalHome) },
4549

4650
{ path: '', redirectTo: 'home', pathMatch: 'full' },
47-
{ path: '**', redirectTo: 'home' }
48-
51+
{ path: '**', redirectTo: 'home' },
4952
];

apps/fakeoverflow-angular/src/app/pages/home/home/PostDetails/details.html

Lines changed: 0 additions & 30 deletions
This file was deleted.

apps/fakeoverflow-angular/src/app/pages/home/home/PostDetails/details.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

apps/fakeoverflow-angular/src/app/pages/home/home/create-post/post.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ <h1 class="text-3xl font-bold text-gray-900 mb-6">Ask question</h1>
66
<form [formGroup]="formGroup" (ngSubmit)="submit()" novalidate class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 space-y-6">
77
<div>
88
<label class="block text-sm font-medium text-gray-700 mb-2">Title</label>
9-
<input formControlName="title" name="title" class="w-full px-4 py-2.5 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Be specific">
9+
<input formControlName="title" name="title" class="w-full px-4 py-2.5 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Please enter your title">
1010
<div class="mt-1 text-sm text-red-600" *ngIf="formGroup.controls['title']?.touched && formGroup.controls['title']?.invalid">Enter at least 10 characters</div>
1111
</div>
1212

1313
<div>
1414
<label class="block text-sm font-medium text-gray-700 mb-2">Body</label>
15-
<textarea name="body" formControlName="content" rows="8" class="w-full px-4 py-2.5 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describe your question"></textarea>
15+
<textarea name="body" formControlName="content" rows="8" class="w-full px-4 py-2.5 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Describle the post in detail"></textarea>
1616
<div class="mt-1 text-sm text-red-600" *ngIf="formGroup.controls['title']?.touched && formGroup.controls['title']?.invalid">Enter at least 20 characters</div>
1717
</div>
1818
<div class="flex items-center justify-between">
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<app-navbar></app-navbar>
2+
3+
<div class="min-h-screen bg-gray-50">
4+
<div class="max-w-[100rem] mx-auto flex flex-col lg:flex-row gap-8 px-6 lg:px-10 py-10">
5+
6+
<div class="flex-1 space-y-6">
7+
<div *ngIf="!loading && post" class="flex flex-col gap-2">
8+
<app-post-title [post]="post"></app-post-title>
9+
<app-post-question class="mb-5" [post]="post"></app-post-question>
10+
<app-post-answer [post]="post"></app-post-answer>
11+
</div>
12+
</div>
13+
14+
<aside class="hidden lg:block w-[300px] shrink-0">
15+
<div class="bg-white border border-gray-200 rounded-2xl shadow-sm p-5">
16+
<h2 class="text-lg font-semibold text-gray-800 mb-3 border-b border-gray-100 pb-2">
17+
Related Posts
18+
</h2>
19+
<ul class="space-y-3 text-sm">
20+
<li><a href="#" class="text-blue-600 hover:text-blue-700 hover:underline">What are interest rate cuts?</a></li>
21+
<li><a href="#" class="text-blue-600 hover:text-blue-700 hover:underline">Impact of Fed decisions on markets</a></li>
22+
<li><a href="#" class="text-blue-600 hover:text-blue-700 hover:underline">AI in financial news detection</a></li>
23+
</ul>
24+
</div>
25+
</aside>
26+
27+
</div>
28+
</div>

apps/fakeoverflow-angular/src/app/pages/home/home/PostDetails/details.scss renamed to apps/fakeoverflow-angular/src/app/pages/home/home/details/details.scss

File renamed without changes.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { Component, OnInit , inject } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { FormsModule, NgForm } from '@angular/forms';
4+
import { ActivatedRoute } from '@angular/router';
5+
import {Navbar} from '@shared/navbar/navbar';
6+
import { PostService } from '../../../../../../../../packages/fakeoverflow-angular-services/api/post.service';
7+
import {PostTitle} from '@pages/home/home/details/post-title/post-title';
8+
import {PostQuestion} from '@pages/home/home/details/post-question/post-question';
9+
import {PostAnswer} from '@pages/home/home/details/post-answer/post-answer';
10+
import {FakeoverFlowBackendHttpApiFeaturesPostsViewPostViewPostResponse} from 'fakeoverflow-angular-services';
11+
import {HotToastService} from '@ngxpert/hot-toast';
12+
import {Spinner} from '@services/spinner';
13+
14+
@Component({
15+
selector: 'app-post',
16+
standalone: true,
17+
imports: [Navbar, CommonModule, FormsModule, PostTitle, PostQuestion, PostAnswer],
18+
templateUrl: './details.html',
19+
styleUrl: './details.scss'
20+
})
21+
export class DetailsComponent implements OnInit {
22+
private readonly postService = inject(PostService);
23+
private readonly route = inject(ActivatedRoute);
24+
protected readonly spinnerService = inject(Spinner);
25+
26+
protected post: FakeoverFlowBackendHttpApiFeaturesPostsViewPostViewPostResponse | null = null;
27+
loading = false;
28+
errorMessage = '';
29+
ngOnInit() {
30+
const id = this.route.snapshot.paramMap.get('id');
31+
if (!id) {
32+
this.errorMessage = 'No post ID provided.';
33+
return;
34+
}
35+
this.loading = true;
36+
37+
const pageSpinner = this.spinnerService.for("Loading post");
38+
this.postService.getPostById(id).subscribe({
39+
next: (response) => {
40+
pageSpinner.release()
41+
this.post = response;
42+
this.loading = false;
43+
},
44+
error: (err) => {
45+
console.error('Error loading post:', err);
46+
this.errorMessage = 'Failed to load post.';
47+
this.loading = false;
48+
pageSpinner.release()
49+
}
50+
});
51+
52+
}
53+
}
54+
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<div class="bg-white border border-gray-200 rounded-lg shadow-sm p-6">
2+
<h2 class="text-2xl font-semibold text-gray-900 mb-4">Answers</h2>
3+
4+
<div *ngIf="loading" class="text-gray-600 py-4">Loading answers...</div>
5+
<div *ngIf="errorMessage" class="text-red-600 py-4">{{ errorMessage }}</div>
6+
7+
<!-- List of answers -->
8+
<div *ngIf="!loading && answers?.length > 0" class="space-y-6">
9+
<div
10+
*ngFor="let answer of answers"
11+
class="border border-gray-200 rounded-lg shadow-sm p-4"
12+
>
13+
<div class="flex items-start space-x-4">
14+
<!-- Voting -->
15+
<div class="flex flex-col items-center text-gray-500">
16+
<button pButton icon="pi pi-chevron-up" class="p-button-text"></button>
17+
<span class="text-sm font-medium">0</span>
18+
<button pButton icon="pi pi-chevron-down" class="p-button-text"></button>
19+
</div>
20+
21+
<!-- Answer Body -->
22+
<div class="flex-1">
23+
<p class="text-gray-800 whitespace-pre-line leading-relaxed mb-3">
24+
{{ answer.content }}
25+
</p>
26+
27+
<div class="flex items-center text-sm text-gray-500">
28+
<img
29+
*ngIf="answer.createdOn?.user?.profilePicture"
30+
[src]="answer.createdOn.user.profilePicture"
31+
alt="Profile"
32+
class="w-6 h-6 rounded-full"
33+
/>
34+
<span class="ml-2">{{ answer.createdOn?.user?.name }}</span>
35+
<span class="ml-1">· {{ answer.createdOn?.activityOn | date: 'medium' }}</span>
36+
</div>
37+
</div>
38+
</div>
39+
</div>
40+
</div>
41+
42+
<!-- No answers -->
43+
<div *ngIf="!loading && (!answers || answers.length === 0)" class="text-gray-500 py-4">
44+
No answers yet. Be the first to respond!
45+
</div>
46+
</div>

apps/fakeoverflow-angular/src/app/pages/home/home/details/post-answer/post-answer.scss

Whitespace-only changes.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {Component, input, signal} from '@angular/core';
2+
import {FakeoverFlowBackendHttpApiFeaturesPostsViewPostViewPostResponse} from 'fakeoverflow-angular-services';
3+
import {ButtonDirective} from 'primeng/button';
4+
import {DatePipe} from '@angular/common';
5+
6+
@Component({
7+
selector: 'app-post-answer',
8+
imports: [
9+
ButtonDirective,
10+
DatePipe
11+
],
12+
templateUrl: './post-answer.html',
13+
styleUrl: './post-answer.scss'
14+
})
15+
export class PostAnswer {
16+
public post = input.required<FakeoverFlowBackendHttpApiFeaturesPostsViewPostViewPostResponse>();
17+
protected readonly errorMessage = signal<string | null>(null);
18+
}

0 commit comments

Comments
 (0)