diff --git a/client/src/features/characters/components/actions-tab.tsx b/client/src/features/characters/components/actions-tab.tsx
index 70585de..614e9d4 100644
--- a/client/src/features/characters/components/actions-tab.tsx
+++ b/client/src/features/characters/components/actions-tab.tsx
@@ -4,6 +4,8 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/shared/components/ui
import { Input } from '@/shared/components/ui/input';
import { Button } from '@/shared/components/ui/button';
import { ActionIcon, ActionTypeBadge } from '@/shared/components/ui/action-icon';
+import { FeatDetailModal } from './feat-detail-modal';
+import type { CharacterFeat } from '@/shared/types';
interface ActionResult {
criticalSuccess?: string;
@@ -133,12 +135,7 @@ function ActionCard({ action, isExpanded, onToggle }: { action: Action; isExpand
}
interface ActionsTabProps {
- characterFeats?: Array<{
- id: string;
- name: string;
- nameGerman?: string | null;
- source: string;
- }>;
+ characterFeats?: CharacterFeat[];
}
type CategoryKey = 'class' | 'action' | 'reaction' | 'free' | 'exploration' | 'downtime' | 'varies';
@@ -189,6 +186,7 @@ export function ActionsTab({ characterFeats = [] }: ActionsTabProps) {
const [expandedActionId, setExpandedActionId] = useState
Vollständige Beschreibung
++ Vollständige Beschreibung (Englisch) +
{featDetails.description}
diff --git a/client/src/features/characters/utils/export-character-html.ts b/client/src/features/characters/utils/export-character-html.ts index 16c54bb..46afb02 100644 --- a/client/src/features/characters/utils/export-character-html.ts +++ b/client/src/features/characters/utils/export-character-html.ts @@ -161,8 +161,8 @@ export function generateCharacterHTML(character: Character): string { const hasPreparedItems = character.preparedItems && character.preparedItems.length > 0; // Group items by equipped status - const equippedItems = character.items?.filter(i => i.isEquipped) || []; - const carriedItems = character.items?.filter(i => !i.isEquipped) || []; + const equippedItems = character.items?.filter(i => i.equipped) || []; + const carriedItems = character.items?.filter(i => !i.equipped) || []; // Calculate total bulk const totalBulk = character.items?.reduce((sum, item) => { diff --git a/server/src/modules/feats/feats.service.ts b/server/src/modules/feats/feats.service.ts index 6d51791..2e5aee2 100644 --- a/server/src/modules/feats/feats.service.ts +++ b/server/src/modules/feats/feats.service.ts @@ -110,9 +110,18 @@ export class FeatsService { } async findById(id: string) { - return this.prisma.feat.findUnique({ + const feat = await this.prisma.feat.findUnique({ where: { id }, }); + + if (!feat) return null; + + // Generate translation on-demand if missing + if (!feat.nameGerman || !feat.summaryGerman) { + return this.ensureTranslation(feat); + } + + return feat; } async findByName(name: string) { @@ -133,6 +142,13 @@ export class FeatsService { }); } + if (!feat) return null; + + // Generate translation on-demand if missing + if (!feat.nameGerman || !feat.summaryGerman) { + return this.ensureTranslation(feat); + } + return feat; } @@ -179,6 +195,38 @@ export class FeatsService { return Array.from(traitsSet).sort(); } + // Ensure a feat has German translations, generating them if needed + private async ensureTranslation(feat: { + id: string; + name: string; + summary?: string | null; + nameGerman?: string | null; + summaryGerman?: string | null; + }) { + try { + const translation = await this.translationsService.getTranslation( + TranslationType.FEAT, + feat.name, + feat.summary || undefined, + ); + + // Update the database with the translation + const updated = await this.prisma.feat.update({ + where: { id: feat.id }, + data: { + nameGerman: translation.germanName, + summaryGerman: translation.germanDescription, + }, + }); + + return updated; + } catch (error) { + // If translation fails, return the original feat + console.error(`Failed to translate feat ${feat.name}:`, error); + return feat; + } + } + // Get translation for a feat (with caching) async getTranslatedFeat(feat: { name: string; summary?: string | null }) { const translation = await this.translationsService.getTranslation(