Allow updating rating in review modal

This commit is contained in:
Amelia 2025-04-25 23:59:15 +02:00
parent 2487eb97e1
commit 114ee4f09b
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
7 changed files with 23 additions and 6 deletions

View file

@ -46,6 +46,7 @@ public class ReviewController : BaseApiController
.WithBody(dto.Body) .WithBody(dto.Body)
.WithSeriesId(dto.SeriesId) .WithSeriesId(dto.SeriesId)
.WithTagline(string.Empty) .WithTagline(string.Empty)
.WithRating(dto.Rating)
.Build(); .Build();
if (rating.Id == 0) if (rating.Id == 0)
@ -83,6 +84,7 @@ public class ReviewController : BaseApiController
.WithSeriesId(dto.SeriesId) .WithSeriesId(dto.SeriesId)
.WithVolumeId(chapter.VolumeId) .WithVolumeId(chapter.VolumeId)
.WithChapterId(chapter.Id) .WithChapterId(chapter.Id)
.WithRating(dto.Rating)
.WithReview(dto.Body) .WithReview(dto.Body)
.Build(); .Build();

View file

@ -6,5 +6,6 @@ namespace API.DTOs.SeriesDetail;
public class UpdateUserReviewDto public class UpdateUserReviewDto
{ {
public int SeriesId { get; set; } public int SeriesId { get; set; }
public int Rating { get; set; }
public string Body { get; set; } public string Body { get; set; }
} }

View file

@ -34,7 +34,7 @@ export class ChapterService {
return this.httpClient.get<Array<UserReview>>(this.baseUrl + 'chapter/review?chapterId='+chapterId); return this.httpClient.get<Array<UserReview>>(this.baseUrl + 'chapter/review?chapterId='+chapterId);
} }
updateChapterReview(seriesId: number, chapterId: number, body: string) { updateChapterReview(seriesId: number, chapterId: number, body: string, rating: number) {
return this.httpClient.post<UserReview>(this.baseUrl + 'review/chapter/'+chapterId, {seriesId, body}); return this.httpClient.post<UserReview>(this.baseUrl + 'review/chapter/'+chapterId, {seriesId, body});
} }

View file

@ -208,9 +208,9 @@ export class SeriesService {
deleteReview(seriesId: number) { deleteReview(seriesId: number) {
return this.httpClient.delete(this.baseUrl + 'review?seriesId=' + seriesId); return this.httpClient.delete(this.baseUrl + 'review?seriesId=' + seriesId);
} }
updateReview(seriesId: number, body: string) { updateReview(seriesId: number, body: string, rating: number) {
return this.httpClient.post<UserReview>(this.baseUrl + 'review', { return this.httpClient.post<UserReview>(this.baseUrl + 'review', {
seriesId, body seriesId, body, rating
}); });
} }

View file

@ -5,6 +5,7 @@ export interface UserReview {
libraryId: number; libraryId: number;
volumeId?: number; volumeId?: number;
chapterId?: number; chapterId?: number;
rating: number;
score: number; score: number;
username: string; username: string;
body: string; body: string;

View file

@ -8,6 +8,10 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<form [formGroup]="reviewGroup"> <form [formGroup]="reviewGroup">
<ngx-stars [initialStars]="review.rating" (ratingOutput)="updateRating($event)" [size]="2"
[maxStars]="5" [color]="starColor"></ngx-stars>
<div class="row g-0 mt-2"> <div class="row g-0 mt-2">
<label for="review" class="form-label">{{t('review-label')}}</label> <label for="review" class="form-label">{{t('review-label')}}</label>
<textarea id="review" class="form-control" formControlName="reviewBody" rows="3" [minlength]="minLength" <textarea id="review" class="form-control" formControlName="reviewBody" rows="3" [minlength]="minLength"

View file

@ -8,6 +8,8 @@ import {ConfirmService} from "../../shared/confirm.service";
import {ToastrService} from "ngx-toastr"; import {ToastrService} from "ngx-toastr";
import {ChapterService} from "../../_services/chapter.service"; import {ChapterService} from "../../_services/chapter.service";
import {of} from "rxjs"; import {of} from "rxjs";
import {NgxStarsModule} from "ngx-stars";
import {ThemeService} from "../../_services/theme.service";
export enum ReviewSeriesModalCloseAction { export enum ReviewSeriesModalCloseAction {
Create, Create,
@ -23,7 +25,7 @@ export interface ReviewSeriesModalCloseEvent {
@Component({ @Component({
selector: 'app-review-series-modal', selector: 'app-review-series-modal',
imports: [ReactiveFormsModule, TranslocoDirective], imports: [ReactiveFormsModule, TranslocoDirective, NgxStarsModule],
templateUrl: './review-modal.component.html', templateUrl: './review-modal.component.html',
styleUrls: ['./review-modal.component.scss'], styleUrls: ['./review-modal.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
@ -36,11 +38,14 @@ export class ReviewModalComponent implements OnInit {
private readonly cdRef = inject(ChangeDetectorRef); private readonly cdRef = inject(ChangeDetectorRef);
private readonly confirmService = inject(ConfirmService); private readonly confirmService = inject(ConfirmService);
private readonly toastr = inject(ToastrService); private readonly toastr = inject(ToastrService);
private readonly themeService = inject(ThemeService);
protected readonly minLength = 5; protected readonly minLength = 5;
@Input({required: true}) review!: UserReview; @Input({required: true}) review!: UserReview;
reviewGroup!: FormGroup; reviewGroup!: FormGroup;
starColor = this.themeService.getCssVariable('--rating-star-color');
ngOnInit(): void { ngOnInit(): void {
this.reviewGroup = new FormGroup({ this.reviewGroup = new FormGroup({
reviewBody: new FormControl(this.review.body, [Validators.required, Validators.minLength(this.minLength)]), reviewBody: new FormControl(this.review.body, [Validators.required, Validators.minLength(this.minLength)]),
@ -48,6 +53,10 @@ export class ReviewModalComponent implements OnInit {
this.cdRef.markForCheck(); this.cdRef.markForCheck();
} }
updateRating($event: number) {
this.review.rating = $event;
}
close() { close() {
this.modal.close({success: false, review: this.review, action: ReviewSeriesModalCloseAction.Close}); this.modal.close({success: false, review: this.review, action: ReviewSeriesModalCloseAction.Close});
} }
@ -76,9 +85,9 @@ export class ReviewModalComponent implements OnInit {
let obs; let obs;
if (!this.review.chapterId) { if (!this.review.chapterId) {
obs = this.seriesService.updateReview(this.review.seriesId, model.reviewBody); obs = this.seriesService.updateReview(this.review.seriesId, model.reviewBody, this.review.rating);
} else { } else {
obs = this.chapterService.updateChapterReview(this.review.seriesId, this.review.chapterId, model.reviewBody); obs = this.chapterService.updateChapterReview(this.review.seriesId, this.review.chapterId, model.reviewBody, this.review.rating);
} }
obs?.subscribe(review => { obs?.subscribe(review => {