fix: use ActivityType enum values instead of string literals

Changed all activity type assignments to use ActivityType enum members
(ActivityType.suggestion, ActivityType.like, etc.) instead of string
literals ('SUGGESTION', 'LIKE', etc.) to ensure proper type discrimination
in the union type.

Frontend:
- Import ActivityType as value (not just type)
- Update switch cases to use enum members
- Expose ActivityType in component for template access

Backend:
- Import ActivityType as value
- Use enum members in all activity mappings

This ensures TypeScript can properly discriminate the union type and
provides type safety throughout the activity feed.
This commit is contained in:
2026-02-20 00:04:35 -08:00
committed by Naomi Carrigan
parent 808df775a4
commit 391ea6d9f6
2 changed files with 14 additions and 11 deletions
+5 -6
View File
@@ -7,10 +7,9 @@
import type {
Activity,
ActivityFeedResponse,
ActivityType,
ActivityUser,
} from "@library/shared-types";
import { ACHIEVEMENTS } from "@library/shared-types";
import { ACHIEVEMENTS, ActivityType } from "@library/shared-types";
import { prisma } from "../lib/prisma";
export class ActivityService {
@@ -89,7 +88,7 @@ export class ActivityService {
return suggestions.map((suggestion) => ({
id: `suggestion-${suggestion.id}`,
type: "SUGGESTION" as const,
type: ActivityType.suggestion,
user: suggestion.user as ActivityUser,
entityType: suggestion.entityType,
suggestionTitle: suggestion.title,
@@ -139,7 +138,7 @@ export class ActivityService {
);
return {
id: `like-${like.id}`,
type: "LIKE" as const,
type: ActivityType.like,
user: like.user as ActivityUser,
entityType: like.entityType,
entityId: like.entityId,
@@ -229,7 +228,7 @@ export class ActivityService {
return {
id: `comment-${comment.id}`,
type: "COMMENT" as const,
type: ActivityType.comment,
user: comment.user as ActivityUser,
entityType,
entityId,
@@ -282,7 +281,7 @@ export class ActivityService {
const achievement = ACHIEVEMENTS[ua.achievementKey];
return {
id: `achievement-${ua.id}`,
type: "ACHIEVEMENT" as const,
type: ActivityType.achievement,
user: ua.user as ActivityUser,
achievementKey: ua.achievementKey,
achievementName: achievement.title,
@@ -7,7 +7,8 @@
import { Component, OnInit, inject, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterLink } from '@angular/router';
import type { Activity, ActivityType } from '@library/shared-types';
import type { Activity } from '@library/shared-types';
import { ActivityType } from '@library/shared-types';
import { ActivityService } from '../../services/activity.service';
@Component({
@@ -64,7 +65,7 @@ import { ActivityService } from '../../services/activity.service';
<div class="activity-content">
@switch (activity.type) {
@case ('SUGGESTION') {
@case (ActivityType.suggestion) {
<div class="activity-suggestion">
<span class="activity-icon">💡</span>
<span class="activity-text">
@@ -76,7 +77,7 @@ import { ActivityService } from '../../services/activity.service';
</span>
</div>
}
@case ('LIKE') {
@case (ActivityType.like) {
<div class="activity-like">
<span class="activity-icon">❤️</span>
<span class="activity-text">
@@ -87,7 +88,7 @@ import { ActivityService } from '../../services/activity.service';
</span>
</div>
}
@case ('COMMENT') {
@case (ActivityType.comment) {
<div class="activity-comment">
<span class="activity-icon">💬</span>
<span class="activity-text">
@@ -99,7 +100,7 @@ import { ActivityService } from '../../services/activity.service';
<p class="comment-preview">"{{ activity.commentPreview }}"</p>
</div>
}
@case ('ACHIEVEMENT') {
@case (ActivityType.achievement) {
<div class="activity-achievement">
<span class="activity-icon">{{ activity.achievementIcon }}</span>
<span class="activity-text">
@@ -360,6 +361,9 @@ import { ActivityService } from '../../services/activity.service';
export class ActivityFeedComponent implements OnInit {
private activityService = inject(ActivityService);
// Make ActivityType accessible in template
ActivityType = ActivityType;
activities = signal<Activity[]>([]);
loading = signal(true);
loadingMore = signal(false);