This commit is contained in:
2025-12-11 11:25:22 +01:00
parent 6a427eab57
commit e4c1be628d
86 changed files with 1222 additions and 736 deletions

View File

@@ -1,8 +1,8 @@
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import Image from 'next/image';
import type { FeedItem } from '@gridpilot/social/domain/entities/FeedItem';
import { getDriverRepository, getImageService, getSocialRepository } from '@/lib/di-container';
import type { FeedItemDTO } from '@gridpilot/social/application/dto/FeedItemDTO';
import { getDriverRepository, getImageService } from '@/lib/di-container';
function timeAgo(timestamp: Date): string {
const diffMs = Date.now() - timestamp.getTime();
@@ -15,44 +15,32 @@ function timeAgo(timestamp: Date): string {
return `${diffDays} d ago`;
}
async function resolveActor(item: FeedItem) {
async function resolveActor(item: FeedItemDTO) {
const driverRepo = getDriverRepository();
const imageService = getImageService();
const socialRepo = getSocialRepository();
if (item.actorFriendId) {
// Try social graph first (friend display name/avatar)
try {
const friend = await socialRepo.getFriendByDriverId?.(item.actorFriendId);
if (friend) {
return {
name: friend.displayName ?? friend.driverName ?? `Driver ${item.actorFriendId}`,
avatarUrl: friend.avatarUrl ?? imageService.getDriverAvatar(item.actorFriendId),
};
}
} catch {
// fall through to driver lookup
}
const actorId = item.actorFriendId ?? item.actorDriverId;
if (!actorId) {
return null;
}
// Fallback to driver entity + image service
try {
const driver = await driverRepo.findById(item.actorFriendId);
if (driver) {
return {
name: driver.name,
avatarUrl: imageService.getDriverAvatar(driver.id),
};
}
} catch {
// ignore and return null below
try {
const driver = await driverRepo.findById(actorId);
if (driver) {
return {
name: driver.name,
avatarUrl: imageService.getDriverAvatar(driver.id),
};
}
} catch {
// ignore and fall through to generic rendering
}
return null;
}
interface FeedItemCardProps {
item: FeedItem;
item: FeedItemDTO;
}
export default function FeedItemCard({ item }: FeedItemCardProps) {

View File

@@ -1,5 +1,5 @@
import Card from '@/components/ui/Card';
import type { FeedItem } from '@gridpilot/social/domain/entities/FeedItem';
import type { FeedItemDTO } from '@gridpilot/social/application/dto/FeedItemDTO';
import type { Race } from '@gridpilot/racing/domain/entities/Race';
import type { RaceWithResultsDTO } from '@gridpilot/testing-support';
import FeedList from '@/components/feed/FeedList';
@@ -7,7 +7,7 @@ import UpcomingRacesSidebar from '@/components/races/UpcomingRacesSidebar';
import LatestResultsSidebar from '@/components/races/LatestResultsSidebar';
interface FeedLayoutProps {
feedItems: FeedItem[];
feedItems: FeedItemDTO[];
upcomingRaces: Race[];
latestResults: RaceWithResultsDTO[];
}

View File

@@ -1,9 +1,9 @@
import FeedEmptyState from '@/components/feed/FeedEmptyState';
import FeedItemCard from '@/components/feed/FeedItemCard';
import type { FeedItem } from '@gridpilot/social/domain/entities/FeedItem';
import type { FeedItemDTO } from '@gridpilot/social/application/dto/FeedItemDTO';
interface FeedListProps {
items: FeedItem[];
items: FeedItemDTO[];
}
export default function FeedList({ items }: FeedListProps) {