Mise en ligne de la version 0.2.0
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<div class="chapter-create-page">
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Créer un nouveau chapitre</h1>
|
||||
<p class="arc-ref" *ngIf="arcName">Arc : {{ arcName }}</p>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="form" (ngSubmit)="submit()" class="chapter-form">
|
||||
|
||||
<div class="field">
|
||||
<label>Nom du chapitre *</label>
|
||||
<input
|
||||
type="text"
|
||||
formControlName="name"
|
||||
placeholder="Ex: Chapitre 1: Les Disparitions"
|
||||
[class.invalid]="form.get('name')?.invalid && form.get('name')?.touched"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>Description</label>
|
||||
<textarea
|
||||
formControlName="description"
|
||||
placeholder="Décrivez ce chapitre..."
|
||||
rows="5">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn-primary" [disabled]="form.invalid">
|
||||
Créer le chapitre
|
||||
</button>
|
||||
<button type="button" class="btn-secondary" (click)="cancel()">Annuler</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
.chapter-create-page {
|
||||
padding: 2.5rem 2rem;
|
||||
max-width: 640px;
|
||||
}
|
||||
|
||||
// Overrides locaux :
|
||||
// - titre en violet (au lieu de blanc comme le .page-header global)
|
||||
// - sous-titre .arc-ref spécifique à cet écran (référence à l'arc parent)
|
||||
.page-header {
|
||||
h1 { color: #a5b4fc; }
|
||||
.arc-ref { color: #6b7280; font-size: 0.85rem; margin: 0; }
|
||||
}
|
||||
|
||||
.chapter-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
// Le bouton "Créer" prend toute la largeur restante.
|
||||
.btn-primary { flex: 1; }
|
||||
@@ -0,0 +1,97 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { forkJoin } from 'rxjs';
|
||||
import { LucideAngularModule } from 'lucide-angular';
|
||||
import { CampaignService } from '../../services/campaign.service';
|
||||
import { LayoutService, GlobalItem } from '../../services/layout.service';
|
||||
import { Campaign } from '../../services/campaign.model';
|
||||
import { loadCampaignTreeData, buildCampaignTree } from '../campaign-tree.helper';
|
||||
|
||||
/**
|
||||
* Écran de création d'un nouveau chapitre rattaché à un arc.
|
||||
* Route : /campaigns/:campaignId/arcs/:arcId/chapters/create
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-chapter-create',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ReactiveFormsModule, LucideAngularModule],
|
||||
templateUrl: './chapter-create.component.html',
|
||||
styleUrls: ['./chapter-create.component.scss']
|
||||
})
|
||||
export class ChapterCreateComponent implements OnInit, OnDestroy {
|
||||
form: FormGroup;
|
||||
campaignId = '';
|
||||
arcId = '';
|
||||
arcName = '';
|
||||
private existingChapterCount = 0;
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private campaignService: CampaignService,
|
||||
private layoutService: LayoutService
|
||||
) {
|
||||
this.form = this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
description: ['']
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.campaignId = this.route.snapshot.paramMap.get('campaignId')!;
|
||||
this.arcId = this.route.snapshot.paramMap.get('arcId')!;
|
||||
this.loadLayout();
|
||||
}
|
||||
|
||||
private loadLayout(): void {
|
||||
forkJoin({
|
||||
campaign: this.campaignService.getCampaignById(this.campaignId),
|
||||
allCampaigns: this.campaignService.getAllCampaigns(),
|
||||
treeData: loadCampaignTreeData(this.campaignService, this.campaignId)
|
||||
}).subscribe(({ campaign, allCampaigns, treeData }) => {
|
||||
const currentArc = treeData.arcs.find(a => a.id === this.arcId);
|
||||
this.arcName = currentArc?.name ?? '';
|
||||
this.existingChapterCount = treeData.chaptersByArc[this.arcId]?.length ?? 0;
|
||||
|
||||
const globalItems: GlobalItem[] = allCampaigns.map((c: Campaign) => ({
|
||||
id: c.id!, name: c.name, route: `/campaigns/${c.id}`
|
||||
}));
|
||||
|
||||
this.layoutService.show({
|
||||
title: campaign.name,
|
||||
items: buildCampaignTree(this.campaignId, treeData),
|
||||
footerLabel: 'Toutes les campagnes',
|
||||
createActions: [
|
||||
{ id: 'create-arc', label: '+ Nouvel arc', variant: 'primary', route: `/campaigns/${this.campaignId}/arcs/create` }
|
||||
],
|
||||
globalItems,
|
||||
globalBackLabel: 'Toutes les campagnes',
|
||||
globalBackRoute: '/campaigns'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
submit(): void {
|
||||
if (this.form.invalid) return;
|
||||
this.campaignService.createChapter({
|
||||
name: this.form.value.name,
|
||||
description: this.form.value.description,
|
||||
arcId: this.arcId,
|
||||
order: this.existingChapterCount + 1
|
||||
}).subscribe({
|
||||
next: (created) => this.router.navigate(['/campaigns', this.campaignId, 'arcs', this.arcId, 'chapters', created.id]),
|
||||
error: () => console.error('Erreur lors de la création du chapitre')
|
||||
});
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.router.navigate(['/campaigns', this.campaignId]);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.layoutService.hide();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user