Files
LoreMind/web/src/app/game-systems/game-system-edit/game-system-edit.component.html
IETM_FIXE\ietm6 8cc90bd24d
All checks were successful
Build & Push Images / build (brain) (push) Successful in 1m38s
Build & Push Images / build (core) (push) Successful in 1m59s
Build & Push Images / build-switcher (push) Successful in 17s
Build & Push Images / build (web) (push) Successful in 1m54s
Amélioration du feedback pendant les imports sur les PDF
passage en 0.12.4-beta
2026-06-12 14:35:10 +02:00

175 lines
6.7 KiB
HTML

<div class="gse-page">
<div class="gse-header">
<button class="btn-back" (click)="back()">
<lucide-icon [img]="ArrowLeft" [size]="14"></lucide-icon>
Retour à la liste
</button>
<h1>
<lucide-icon [img]="Dices" [size]="22"></lucide-icon>
{{ id ? 'Éditer le système' : 'Nouveau système de JDR' }}
</h1>
</div>
<div class="gse-form">
<div class="field">
<label for="gs-name">Nom *</label>
<input id="gs-name" type="text" [(ngModel)]="name" name="name" placeholder="Ex: Nimble, D&D 5.1 SRD, Mon Homebrew..." />
</div>
<div class="field">
<label for="gs-description">Description courte</label>
<textarea id="gs-description" [(ngModel)]="description" name="description" rows="2" placeholder="En une ligne, de quoi parle ce système ?"></textarea>
</div>
<div class="field">
<label for="gs-author">Auteur</label>
<input id="gs-author" type="text" [(ngModel)]="author" name="author" placeholder="Ex: Hasbro, Homebrew, moi-même..." />
</div>
<!-- Sections de règles -->
<div class="sections-area">
<h2 class="sections-title">Règles du système</h2>
<p class="sections-hint">
Une section = un thème. L'IA injectera automatiquement les sections pertinentes
selon ce qu'elle génère (combat → Combat/Monstres, PNJ → Classes, arc → Lore/Factions).
</p>
<!-- Import d'un PDF de règles : l'IA propose un découpage en sections,
que l'utilisateur révise ci-dessous avant d'enregistrer. -->
<div class="import-row">
<input #pdfInput type="file" accept="application/pdf,.pdf" hidden (change)="onPdfSelected($event)" />
<button type="button" class="btn-import" [disabled]="importing" (click)="pdfInput.click()">
<lucide-icon [img]="Upload" [size]="14"></lucide-icon>
{{ importing ? 'Import en cours…' : 'Importer un PDF de règles' }}
</button>
@if (!importing) {
<span class="import-hint">L'IA propose un découpage en sections — vous révisez avant d'enregistrer.</span>
}
</div>
<!-- Progression live de l'import (étape + barre + sections trouvées). -->
@if (importing) {
<div class="import-progress">
<p class="import-phase">{{ importPhase }}</p>
@if (importProgress) {
<div class="progress-bar">
<div class="progress-fill"
[style.width.%]="importProgress.total ? (importProgress.current / importProgress.total) * 100 : 0">
</div>
</div>
}
@if (importStatus) {
<p class="import-status" role="status">{{ importStatus }}</p>
}
@if (importFound.length) {
<p class="import-found">
Sections trouvées : {{ importFound.join(' · ') }}
</p>
}
</div>
}
@if (importNote) {
<p class="import-note">{{ importNote }}</p>
}
@if (importError) {
<p class="import-error">{{ importError }}</p>
}
<div class="section-list">
@for (section of sections; track section; let i = $index) {
<div class="section-card" [class.collapsed]="section.collapsed">
<div class="section-head">
<button type="button" class="btn-collapse" (click)="toggleCollapse(section)">
<lucide-icon [img]="section.collapsed ? ChevronRight : ChevronDown" [size]="16"></lucide-icon>
</button>
<input
type="text"
class="section-title-input"
[(ngModel)]="section.title"
[name]="'title-' + i"
placeholder="Nom de la section (ex: Combat)"
/>
<button type="button" class="btn-remove" (click)="removeSection(i)" title="Supprimer cette section">
<lucide-icon [img]="Trash2" [size]="14"></lucide-icon>
</button>
</div>
@if (!section.collapsed) {
<textarea
class="section-content"
[(ngModel)]="section.content"
[name]="'content-' + i"
rows="6"
placeholder="Décrivez les règles de cette section..."
></textarea>
}
</div>
}
@if (sections.length === 0) {
<div class="empty-hint">
Aucune section pour l'instant — ajoutez-en une avec les boutons ci-dessous.
</div>
}
</div>
<div class="add-row">
<span class="add-label">Ajouter une section :</span>
@for (name of suggestedSections; track name) {
<button
type="button"
class="chip"
[class.disabled]="isSectionUsed(name)"
(click)="addSuggested(name)"
[disabled]="isSectionUsed(name)">
<lucide-icon [img]="Plus" [size]="12"></lucide-icon>
{{ name }}
</button>
}
<button type="button" class="chip chip-custom" (click)="addBlank()">
<lucide-icon [img]="Plus" [size]="12"></lucide-icon>
Autre…
</button>
</div>
</div>
<!-- Templates de fiches PJ/PNJ -->
<div class="templates-area">
<h2 class="sections-title">Fiches de personnages</h2>
<p class="sections-hint">
Definissez la structure des fiches PJ et PNJ pour ce systeme. Les champs
universels (nom, portrait, header) sont automatiques — ne rajoutez ici
que les champs specifiques au systeme (Histoire, PV, Stats…).
</p>
<app-template-fields-editor
label="Champs de la fiche PJ"
hint="Affiches lors de la creation/edition d'un personnage joueur."
[fields]="characterTemplate"
[suggestions]="characterFieldSuggestions"
(fieldsChange)="characterTemplate = $event">
</app-template-fields-editor>
<app-template-fields-editor
label="Champs de la fiche PNJ"
hint="Affiches lors de la creation/edition d'un personnage non-joueur."
[fields]="npcTemplate"
[suggestions]="npcFieldSuggestions"
(fieldsChange)="npcTemplate = $event">
</app-template-fields-editor>
</div>
<div class="actions">
<button type="button" class="btn-primary" [disabled]="!name.trim()" (click)="submit()">
<lucide-icon [img]="Save" [size]="16"></lucide-icon>
{{ id ? 'Enregistrer' : 'Créer' }}
</button>
<button type="button" class="btn-secondary" (click)="back()">Annuler</button>
</div>
</div>
</div>