Skip to content

Commit

Permalink
added page stepping
Browse files Browse the repository at this point in the history
  • Loading branch information
ortwic committed Mar 25, 2024
1 parent fe30710 commit ff7949c
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
}

& textarea {
height: calc(var(--height) - 2rem);
height: calc(var(--height) - 2rem) !important;
}
}
2 changes: 1 addition & 1 deletion src/app/components/stepper/stepper.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<section>
@for (item of controls; track $index) {
<div [@next]="show($index) ? 'expanded' : 'collapsed'">
<div [@next]="show($index)">
<ng-container *ngTemplateOutlet="template; context: { $implicit: item, disabled: disabled($index) }">
</ng-container>
</div>
Expand Down
87 changes: 41 additions & 46 deletions src/app/components/stepper/stepper.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,48 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { expandTrigger } from '../../animations.helper';

@Component({
selector: 'app-stepper',
standalone: true,
imports: [
CommonModule,
MatButtonModule,
MatIconModule,
MatProgressSpinnerModule,
],
templateUrl: './stepper.component.html',
styleUrl: './stepper.component.scss',
animations: [ expandTrigger('next') ]
selector: 'app-stepper',
standalone: true,
imports: [CommonModule, MatButtonModule, MatIconModule, MatProgressSpinnerModule],
templateUrl: './stepper.component.html',
styleUrl: './stepper.component.scss',
animations: [expandTrigger('next')],
})
export class StepperComponent<T> {
@Input({ alias: 'controls', required: true })
controls!: T[];

@Input({ alias: 'template', required: true })
template!: TemplateRef<unknown>;

@Output('completed')
completed = new EventEmitter();

private step = 0;
done = false;

get last(): boolean {
return this.step >= this.controls.length - 1;
}

get progress(): number {
return (this.step + 1) / this.controls.length * 100;
}

show(index: number): boolean {
return index <= this.step;
}

disabled(index: number): boolean {
return index !== this.step;
}

next(): void {
this.step++;

if (this.step === this.controls.length) {
this.done = true;
this.completed.emit();
@Input({ alias: 'controls', required: true })
controls!: T[];

@Input({ alias: 'template', required: true })
template!: TemplateRef<unknown>;

@Output('completed')
completed = new EventEmitter();

private step = 0;
done = false;

get last(): boolean {
return this.step >= this.controls.length - 1;
}

get progress(): number {
return ((this.step + 1) / this.controls.length) * 100;
}

show(index: number): 'expanded' | 'collapsed' {
return index <= this.step ? 'expanded' : 'collapsed';
}

disabled(index: number): boolean {
return index !== this.step;
}

next(): void {
this.step++;

if (this.step === this.controls.length) {
this.done = true;
this.completed.emit();
}
}
}
}
11 changes: 5 additions & 6 deletions src/app/models/page.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ export interface HeroSection {
image: string;
}

type PageContent = MarkdownContent
| QuoteContent
| FormStepperContent
| IFrameContent
| SectionContent
| SliderContent;
export type PageContent = MarkdownContent
| FormStepperContent
| IFrameContent
| SectionContent
| SliderContent;
17 changes: 9 additions & 8 deletions src/app/pages/page/page.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@
<app-hero-section [hero-section]="page.hero_section"/>

@for (item of page.content; track $index) {

@if (item.type === 'iframe' && item.value) {
<div class="content">
<div class="content" [@next]="show($index)"]>
<iframe [src]="item.value.src | safeUrl" [title]="item.value.title"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen width="560" height="315" frameborder="0"></iframe>
</div>
} @else if (item.type === 'text') {
<div class="content" [innerHtml]="item.value | marked"></div>
<div class="content" [@next]="show($index)" [innerHtml]="item.value | marked"></div>
} @else if (item.type === 'stepper') {
<div class="content">
<app-stepper [controls]="item.value" [template]="form">
<div class="content" [@next]="show($index)">
<app-stepper [controls]="item.value" [template]="form" (completed)="next()">
<ng-template #form let-item let-disabled="disabled">
<app-input-section [item]="item" [disabled]="disabled" />
</ng-template>
</app-stepper>
</div>
} @else if (item.type === 'slider') {
<app-image-slider [images]="item.value" height="50vh" />
<app-image-slider [@next]="show($index)" [images]="item.value" height="50vh" />
} @else {
<pre class="content" title="{{item.type}}">{{item.value | json}}</pre>
<pre class="content" [@next]="show($index)" title="{{item.type}}">{{item.value | json}}</pre>
}
}

Expand All @@ -38,14 +39,14 @@
}
@if (page.nextIndex !== undefined) {
<a role="button" mat-button color="primary" aria-label="Weiter"
[routerLink]="[ '/p', unitIndex, page.nextIndex ]">
[routerLink]="[ '/p', unitIndex, page.nextIndex ]" [disabled]="disabled">
<span class="next">
<mat-icon fontIcon="arrow_forward" /> Weiter&nbsp;
</span>
</a>
} @else {
<a role="button" mat-button color="primary" aria-label="Abschließen"
routerLink="/">
routerLink="/" [disabled]="disabled">
<span class="next">
<mat-icon fontIcon="check_small" /> Abschließen&nbsp;
</span>
Expand Down
32 changes: 31 additions & 1 deletion src/app/pages/page/page.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { StepperComponent } from '../../components/stepper/stepper.component';
import { GuideService } from '../../services/guide.service';
import { SafeUrlPipe } from '../../pipes/safe-url.pipe';
import { MarkedPipe } from '../../pipes/marked.pipe';
import { PageContent } from '../../models/page.model';
import { expandTrigger } from '../../animations.helper';

@Component({
Expand All @@ -38,6 +39,10 @@ export class PageComponent {
private route = inject(ActivatedRoute);
readonly unitIndex = +this.route.snapshot.params['unit'];

private step = 0;
done = false;
next!: () => void;

readonly guideService = inject(GuideService);
readonly currentPage$ = combineLatest([from(this.guideService.getPages(this.unitIndex)), this.route.params]).pipe(
switchMap(([pages, params]) => {
Expand All @@ -50,6 +55,31 @@ export class PageComponent {
nextIndex: next,
});
}),
tap((page) => document.title = page.title + " | Why App")
tap(page => {
this.initBreakpoints(page.content);
document.title = page.title + " | Why App";
})
);

private initBreakpoints(content: PageContent[]) {
const breakpoints = content.reduce((acc, item, index) => {
if (item.type === 'stepper') {
acc.push(index);
}
return acc;
}, [] as number[]);
this.next = () => {
this.step = breakpoints.shift() ?? content.length;
this.done = this.step === content.length;
}
this.next();
}

show(index: number): 'expanded' | 'collapsed' {
return index <= this.step ? 'expanded' : 'collapsed';
}

get disabled() {
return !this.done;
}
}

0 comments on commit ff7949c

Please sign in to comment.