/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { Component, Input, Output, EventEmitter, signal, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import type { Comment } from '@library/shared-types';
import { AuthService } from '../../services/auth.service';
import { SanitizeService } from '../../services/sanitize.service';
import { ReportModalComponent } from '../report-modal/report-modal.component';
@Component({
selector: 'app-comment-display',
standalone: true,
imports: [CommonModule, FormsModule, ReportModalComponent],
template: `
@if (showReportModal()) {
}
`,
styles: [`
.comments-section {
margin-top: 1rem;
}
.comment {
background: #f9fafb;
padding: 0.75rem;
border-radius: 0.375rem;
margin-bottom: 0.75rem;
}
.comment-header {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 0.5rem;
flex-wrap: wrap;
}
.comment-avatar {
width: 2rem;
height: 2rem;
border-radius: 50%;
object-fit: cover;
}
.comment-author {
font-weight: 600;
color: #1f2937;
}
.discord-badge,
.vip-badge,
.mod-badge,
.staff-badge {
padding: 0.125rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.75rem;
font-weight: 600;
}
.discord-badge {
background: #5865f2;
color: white;
}
.vip-badge {
background: #fbbf24;
color: #78350f;
}
.mod-badge {
background: #10b981;
color: white;
}
.staff-badge {
background: #8b5cf6;
color: white;
}
.comment-date {
font-size: 0.75rem;
color: #6b7280;
}
.comment-content {
font-size: 0.9rem;
color: #4b5563;
}
.comment-pending-review {
font-size: 0.9rem;
color: #9b59b6;
font-style: italic;
padding: 0.5rem;
background: #f3e8ff;
border-radius: 0.25rem;
}
.comment-edit-form {
margin-top: 0.5rem;
}
.comment-edit-form textarea {
width: 100%;
padding: 0.5rem;
border: 1px solid #d1d5db;
border-radius: 0.375rem;
font-family: inherit;
resize: vertical;
}
.comment-edit-actions {
display: flex;
gap: 0.5rem;
margin-top: 0.5rem;
}
.no-comments {
text-align: center;
color: #6b7280;
padding: 2rem;
font-style: italic;
}
.btn {
padding: 0.25rem 0.75rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
font-size: 0.875rem;
transition: all 0.2s;
}
.btn-xs {
padding: 0.125rem 0.5rem;
font-size: 0.75rem;
}
.btn-primary {
background: #3b82f6;
color: white;
}
.btn-primary:hover {
background: #2563eb;
}
.btn-secondary {
background: #6b7280;
color: white;
}
.btn-secondary:hover {
background: #4b5563;
}
.btn-danger {
background: #ef4444;
color: white;
}
.btn-danger:hover {
background: #dc2626;
}
.btn-warning {
background: #f59e0b;
color: white;
}
.btn-warning:hover {
background: #d97706;
}
`]
})
export class CommentDisplayComponent {
private readonly authService = inject(AuthService);
readonly sanitizeService = inject(SanitizeService);
@Input({ required: true }) comments = signal([]);
@Output() onEdit = new EventEmitter<{ commentId: string; content: string }>();
@Output() onDelete = new EventEmitter();
editingCommentId = signal(null);
editCommentContent = '';
showReportModal = signal(false);
reportingCommentId = signal('');
formatDate(date: Date | string): string {
const d = new Date(date);
return d.toLocaleDateString('en-GB', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
}
canEditComment(comment: Comment): boolean {
const user = this.authService.user();
if (!user) return false;
return comment.userId === user.id || this.authService.isAdmin();
}
canDeleteComment(comment: Comment): boolean {
const user = this.authService.user();
if (!user) return false;
return comment.userId === user.id || this.authService.isAdmin();
}
canReportComment(comment: Comment): boolean {
const user = this.authService.user();
if (!user) return false;
// Users can report comments they didn't write (but not their own)
return comment.userId !== user.id;
}
startEdit(comment: Comment): void {
this.editingCommentId.set(comment.id);
this.editCommentContent = comment.rawContent ?? comment.content;
}
saveEdit(commentId: string): void {
this.onEdit.emit({ commentId, content: this.editCommentContent });
this.cancelEdit();
}
cancelEdit(): void {
this.editingCommentId.set(null);
this.editCommentContent = '';
}
openReportModal(comment: Comment): void {
this.reportingCommentId.set(comment.id);
this.showReportModal.set(true);
}
closeReportModal(): void {
this.showReportModal.set(false);
this.reportingCommentId.set('');
}
}