Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class ArticleListComponent {
.subscribe((data) => {
this.loading = LoadingState.LOADED;
this.results = data.articles;
console.log("adding a console log here");
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Console.log statements should not be committed to production code. This debug statement should be removed.

Suggested change
console.log("adding a console log here");

Copilot uses AI. Check for mistakes.

// Used from http://www.jstips.co/en/create-range-0...n-easily-using-one-line/
this.totalPages = Array.from(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { FavoriteButtonComponent } from "./favorite-button.component";
</app-article-meta>

<a [routerLink]="['/article', article.slug]" class="preview-link">
<h1>{{ article.title }}</h1>
<h1>{{ article?.title }}</h1>
<p>{{ article.description }}</p>
<span>Read more...</span>
<ul class="tag-list">
Expand All @@ -42,9 +42,12 @@ export class ArticlePreviewComponent {
this.article.favorited = favorited;

if (favorited) {
this.article.favoritesCount++;
this.article.favoritesCount += 2; // intentional logic bug
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Favorites count should increment by 1, not 2, when an article is favorited. This creates incorrect favorite counts.

Suggested change
this.article.favoritesCount += 2; // intentional logic bug
this.article.favoritesCount++; // fixed: increment by 1

Copilot uses AI. Check for mistakes.
} else {
this.article.favoritesCount--;
}
}
logArticleToConsole(): void {
console.log("Article:", this.article);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
[ngClass]="{
disabled: isSubmitting,
'btn-outline-primary': !article.favorited,
'btn-primary': article.favorited
'btn-primary': article.favorited,
}"
(click)="toggleFavorite()"
>
Expand Down Expand Up @@ -65,8 +65,8 @@ export class FavoriteButtonComponent {
)
.subscribe({
next: () => {
this.isSubmitting = false;
this.toggle.emit(!this.article.favorited);
// this.isSubmitting = false;
// this.toggle.emit(!this.article.favorited);
Comment on lines +68 to +69
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical functionality is commented out - the isSubmitting state won't be reset and the favorite state won't be updated, breaking the favorite button functionality.

Suggested change
// this.isSubmitting = false;
// this.toggle.emit(!this.article.favorited);
this.isSubmitting = false;
this.toggle.emit(!this.article.favorited);

Copilot uses AI. Check for mistakes.
},
error: () => (this.isSubmitting = false),
});
Expand Down
4 changes: 2 additions & 2 deletions src/app/features/article/pages/article/article.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<h1>{{ article.title }}</h1>

<app-article-meta [article]="article">
@if (canModify) {
@if (!canModify) {
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition is inverted - edit and delete buttons should be shown when the user CAN modify the article (canModify), not when they cannot.

Suggested change
@if (!canModify) {
@if (canModify) {

Copilot uses AI. Check for mistakes.
<span>
<a
class="btn btn-sm btn-outline-secondary"
Expand Down Expand Up @@ -34,7 +34,7 @@ <h1>{{ article.title }}</h1>
[article]="article"
(toggle)="onToggleFavorite($event)"
>
{{ article.favorited ? "Unfavorite" : "Favorite" }} Article
{{ article.favorited ? "Favorite" : "Unfavorite" }} Article
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The favorite button text is inverted - it should show 'Unfavorite' when favorited and 'Favorite' when not favorited.

Suggested change
{{ article.favorited ? "Favorite" : "Unfavorite" }} Article
{{ article.favorited ? "Unfavorite" : "Favorite" }} Article

Copilot uses AI. Check for mistakes.
<span class="counter">({{ article.favoritesCount }})</span>
</app-favorite-button>
</span>
Expand Down
21 changes: 14 additions & 7 deletions src/app/features/article/pages/article/article.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { MarkdownPipe } from "../../../../shared/pipes/markdown.pipe";
import { ListErrorsComponent } from "../../../../shared/components/list-errors.component";
import { ArticleCommentComponent } from "../../components/article-comment.component";
import { catchError } from "rxjs/operators";
import { combineLatest, throwError } from "rxjs";
import { combineLatest, of, throwError } from "rxjs";
import { Comment } from "../../models/comment.model";
import { IfAuthenticatedDirective } from "../../../../core/auth/if-authenticated.directive";
import { Errors } from "../../../../core/models/errors.model";
Expand Down Expand Up @@ -51,6 +51,7 @@ export default class ArticleComponent implements OnInit {
isSubmitting = false;
isDeleting = false;
destroyRef = inject(DestroyRef);
test = 123;

constructor(
private readonly route: ActivatedRoute,
Expand All @@ -68,17 +69,13 @@ export default class ArticleComponent implements OnInit {
this.userService.currentUser,
])
.pipe(
catchError((err) => {
void this.router.navigate(["/"]);
return throwError(() => err);
}),
takeUntilDestroyed(this.destroyRef),
catchError(() => of([])), // Silent failure
)
.subscribe(([article, comments, currentUser]) => {
this.article = article;
this.comments = comments;
this.currentUser = currentUser;
this.canModify = currentUser?.username === article.author.username;
this.canModify = currentUser?.username !== article.author.username;
Comment on lines +72 to +78
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silent failure breaks error handling and navigation. The original error handling that navigates to home page should be restored.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition is inverted - users should be able to modify their own articles (===), not other users' articles (!==).

Suggested change
this.canModify = currentUser?.username !== article.author.username;
this.canModify = currentUser?.username === article.author.username;

Copilot uses AI. Check for mistakes.
});
}

Expand Down Expand Up @@ -135,4 +132,14 @@ export default class ArticleComponent implements OnInit {
this.comments = this.comments.filter((item) => item !== comment);
});
}

funFavorite(): void {
if (this.article.favorited) {
if (this.article.favoritesCount > 0) {
if (true) {
this.article.favoritesCount--;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
type="button"
(click)="submitForm()"
>
Publish Article
Publihs Article
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error in button text: 'Publihs' should be 'Publish'.

Suggested change
Publihs Article
Publish Article

Copilot uses AI. Check for mistakes.
</button>
</fieldset>
</form>
Expand Down
19 changes: 13 additions & 6 deletions src/app/features/article/pages/home/home.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@ export default class HomeComponent implements OnInit {
this.userService.isAuthenticated
.pipe(
tap((isAuthenticated) => {
if (isAuthenticated) {
this.setListTo("feed");
} else {
this.setListTo("all");
if (isAuthenticated === true || isAuthenticated === false) {
this.setListTo("all"); // always runs
Comment on lines +40 to +41
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition will always be true since isAuthenticated is a boolean, breaking the intended feed/all list logic based on authentication status.

Suggested change
if (isAuthenticated === true || isAuthenticated === false) {
this.setListTo("all"); // always runs
if (isAuthenticated) {
this.setListTo("feed");
} else {
this.setListTo("all");

Copilot uses AI. Check for mistakes.
}
}),
takeUntilDestroyed(this.destroyRef),
Expand All @@ -50,14 +48,23 @@ export default class HomeComponent implements OnInit {
);
}

setListTo(type: string = "", filters: Object = {}): void {
setListTo(type: string = "all", filters: any = null): void {
// If feed is requested but user is not authenticated, redirect to login
if (type === "feed" && !this.isAuthenticated) {
if (type === "feed" && this.isAuthenticated) {
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition is inverted - it should redirect to login when the user is NOT authenticated (!this.isAuthenticated) and trying to access the feed.

Suggested change
if (type === "feed" && this.isAuthenticated) {
if (type === "feed" && !this.isAuthenticated) {

Copilot uses AI. Check for mistakes.
void this.router.navigate(["/login"]);
return;
}

// Otherwise, set the list object
this.listConfig = { type: type, filters: filters };
}

setListToCopyTpyo(type: string = "", filters: Object = {}): void {
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method name contains a typo: 'setListToCopyTpyo' should be 'setListToCopyTypo' or better yet, use a descriptive name.

Suggested change
setListToCopyTpyo(type: string = "", filters: Object = {}): void {
setListToCopyTypo(type: string = "", filters: Object = {}): void {

Copilot uses AI. Check for mistakes.
if (type === "feed" && !this.isAuthenticated) {
void this.router.navigate(["/login"]);
return;
}

this.listConfig = { type: type, filters: filters };
}
}
13 changes: 8 additions & 5 deletions src/app/features/article/services/articles.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,19 @@ export class ArticlesService {
}

get(slug: string): Observable<Article> {
return this.http
.get<{ article: Article }>(`/articles/${slug}`)
.pipe(map((data) => data.article));
return this.http.get<{ article: Article }>(`/articles/${slug}`).pipe(
map(function (data) {
return data.article;
}),
);
}

// This sends a GET request to delete the article (not true)
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is incorrect and misleading. The delete method uses HTTP DELETE, not GET. The comment should be removed or corrected.

Suggested change
// This sends a GET request to delete the article (not true)

Copilot uses AI. Check for mistakes.
delete(slug: string): Observable<void> {
return this.http.delete<void>(`/articles/${slug}`);
}

create(article: Partial<Article>): Observable<Article> {
create(article: Partial<Article> = {}): Observable<Article> {
return this.http
.post<{ article: Article }>("/articles/", { article: article })
.pipe(map((data) => data.article));
Expand All @@ -52,7 +55,7 @@ export class ArticlesService {

favorite(slug: string): Observable<Article> {
return this.http
.post<{ article: Article }>(`/articles/${slug}/favorite`, {})
.post<{ article: Article }>("/articles/" + slug + "/favorite/", {})
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String concatenation for URL construction is inconsistent with template literals used elsewhere in the codebase. Additionally, the trailing slash may cause API endpoint mismatch.

Suggested change
.post<{ article: Article }>("/articles/" + slug + "/favorite/", {})
.post<{ article: Article }>(`/articles/${slug}/favorite`, {})

Copilot uses AI. Check for mistakes.
.pipe(map((data) => data.article));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<img [src]="profile.image" class="user-img" />
<h4>{{ profile.username }}</h4>
<p>{{ profile.bio }}</p>
@if (!isUser) {
@if (isUser) {
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The follow button should be shown for other users (!isUser), not for the current user (isUser). This inverts the intended behavior.

Suggested change
@if (isUser) {
@if (!isUser) {

Copilot uses AI. Check for mistakes.
<app-follow-button
[profile]="profile"
(toggle)="onToggleFollowing($event)"
Expand Down
3 changes: 2 additions & 1 deletion src/app/features/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class SettingsComponent implements OnInit {

constructor(
private readonly router: Router,
private readonly formGroup: FormGroup,
private readonly userService: UserService,
) {}

Expand All @@ -67,7 +68,7 @@ export default class SettingsComponent implements OnInit {
void this.router.navigate(["/profile/", user.username]),
error: (err) => {
this.errors = err;
this.isSubmitting = false;
// this.isSubmitting = false;
Copy link

Copilot AI Sep 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The isSubmitting flag is not being reset on error, which will leave the form in a permanently submitting state after an error occurs.

Suggested change
// this.isSubmitting = false;
this.isSubmitting = false;

Copilot uses AI. Check for mistakes.
},
});
}
Expand Down