generated from nhcarrigan/template
feat: implement user profiles with achievements and primary badge system #58
@@ -4,7 +4,7 @@
|
|||||||
* @author Naomi Carrigan
|
* @author Naomi Carrigan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Comment, CreateCommentDto } from "@library/shared-types";
|
import { Comment, CreateCommentDto, PrimaryBadge } from "@library/shared-types";
|
||||||
import { prisma } from "../lib/prisma";
|
import { prisma } from "../lib/prisma";
|
||||||
import createDOMPurify from "dompurify";
|
import createDOMPurify from "dompurify";
|
||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
@@ -65,6 +65,7 @@ export class CommentService {
|
|||||||
id: comment.user.id,
|
id: comment.user.id,
|
||||||
username: comment.user.username,
|
username: comment.user.username,
|
||||||
avatar: comment.user.avatar || undefined,
|
avatar: comment.user.avatar || undefined,
|
||||||
|
primaryBadge: (comment.user.primaryBadge as PrimaryBadge) || undefined,
|
||||||
inDiscord: comment.user.inDiscord,
|
inDiscord: comment.user.inDiscord,
|
||||||
isVip: comment.user.isVip,
|
isVip: comment.user.isVip,
|
||||||
isMod: comment.user.isMod,
|
isMod: comment.user.isMod,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Component, Input, Output, EventEmitter, signal, inject } from '@angular
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import type { Comment } from '@library/shared-types';
|
import type { Comment } from '@library/shared-types';
|
||||||
|
import { PrimaryBadge } from '@library/shared-types';
|
||||||
import { AuthService } from '../../services/auth.service';
|
import { AuthService } from '../../services/auth.service';
|
||||||
import { SanitizeService } from '../../services/sanitize.service';
|
import { SanitizeService } from '../../services/sanitize.service';
|
||||||
import { ReportModalComponent } from '../report-modal/report-modal.component';
|
import { ReportModalComponent } from '../report-modal/report-modal.component';
|
||||||
@@ -25,17 +26,34 @@ import { ReportModalComponent } from '../report-modal/report-modal.component';
|
|||||||
<img [src]="comment.user.avatar" [alt]="comment.user.username" class="comment-avatar">
|
<img [src]="comment.user.avatar" [alt]="comment.user.username" class="comment-avatar">
|
||||||
}
|
}
|
||||||
<span class="comment-author">{{ comment.user.username }}</span>
|
<span class="comment-author">{{ comment.user.username }}</span>
|
||||||
@if (comment.user.inDiscord) {
|
@if (comment.user.primaryBadge) {
|
||||||
|
<!-- Show only the selected primary badge -->
|
||||||
|
@if (comment.user.primaryBadge === PrimaryBadge.STAFF && comment.user.isStaff) {
|
||||||
|
<span class="staff-badge">Staff</span>
|
||||||
|
}
|
||||||
|
@if (comment.user.primaryBadge === PrimaryBadge.MOD && comment.user.isMod) {
|
||||||
|
<span class="mod-badge">Mod</span>
|
||||||
|
}
|
||||||
|
@if (comment.user.primaryBadge === PrimaryBadge.VIP && comment.user.isVip) {
|
||||||
|
<span class="vip-badge">VIP</span>
|
||||||
|
}
|
||||||
|
@if (comment.user.primaryBadge === PrimaryBadge.DISCORD && comment.user.inDiscord) {
|
||||||
<span class="discord-badge">Discord</span>
|
<span class="discord-badge">Discord</span>
|
||||||
}
|
}
|
||||||
@if (comment.user.isVip) {
|
} @else {
|
||||||
<span class="vip-badge">VIP</span>
|
<!-- Show all badges if no primary badge is selected -->
|
||||||
|
@if (comment.user.isStaff) {
|
||||||
|
<span class="staff-badge">Staff</span>
|
||||||
}
|
}
|
||||||
@if (comment.user.isMod) {
|
@if (comment.user.isMod) {
|
||||||
<span class="mod-badge">Mod</span>
|
<span class="mod-badge">Mod</span>
|
||||||
}
|
}
|
||||||
@if (comment.user.isStaff) {
|
@if (comment.user.isVip) {
|
||||||
<span class="staff-badge">Staff</span>
|
<span class="vip-badge">VIP</span>
|
||||||
|
}
|
||||||
|
@if (comment.user.inDiscord) {
|
||||||
|
<span class="discord-badge">Discord</span>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<span class="comment-date">{{ formatDate(comment.createdAt) }}</span>
|
<span class="comment-date">{{ formatDate(comment.createdAt) }}</span>
|
||||||
@if (canEditComment(comment)) {
|
@if (canEditComment(comment)) {
|
||||||
@@ -244,6 +262,9 @@ export class CommentDisplayComponent {
|
|||||||
private readonly authService = inject(AuthService);
|
private readonly authService = inject(AuthService);
|
||||||
readonly sanitizeService = inject(SanitizeService);
|
readonly sanitizeService = inject(SanitizeService);
|
||||||
|
|
||||||
|
// Expose PrimaryBadge enum for template
|
||||||
|
readonly PrimaryBadge = PrimaryBadge;
|
||||||
|
|
||||||
@Input({ required: true }) comments = signal<Comment[]>([]);
|
@Input({ required: true }) comments = signal<Comment[]>([]);
|
||||||
@Output() edit = new EventEmitter<{ commentId: string; content: string }>();
|
@Output() edit = new EventEmitter<{ commentId: string; content: string }>();
|
||||||
@Output() delete = new EventEmitter<string>();
|
@Output() delete = new EventEmitter<string>();
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
* @author Naomi Carrigan
|
* @author Naomi Carrigan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { PrimaryBadge } from "./auth.types";
|
||||||
|
|
||||||
interface CommentUser {
|
interface CommentUser {
|
||||||
id: string;
|
id: string;
|
||||||
username: string;
|
username: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
|
primaryBadge?: PrimaryBadge;
|
||||||
inDiscord?: boolean;
|
inDiscord?: boolean;
|
||||||
isVip?: boolean;
|
isVip?: boolean;
|
||||||
isMod?: boolean;
|
isMod?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user