File size: 6,152 Bytes
d1bff6b
62b17d6
 
5fb96a0
62b17d6
 
d1bff6b
 
 
5fb96a0
 
 
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62b17d6
5fb96a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62b17d6
 
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fb96a0
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5fb96a0
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993eeba
 
 
 
 
 
 
 
 
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
62b17d6
993eeba
 
 
 
 
d1bff6b
 
 
 
 
 
 
 
993eeba
 
 
d1bff6b
 
 
 
 
 
993eeba
d1bff6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993eeba
d1bff6b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<main class="studio-shell">
  <nav class="top-bar" aria-label="Studio status">
    <strong>MplusKassa Studio</strong>
    <span>Menu deal staat klaar</span>
  </nav>

  <section class="workflow-board" aria-label="Beeldworkflow">
    <header class="board-header">
      <div>
        <p class="eyebrow">Stap 1 / beeldbron</p>
        <h1>Maak een menu-afbeelding.</h1>
        <p class="intro">Start met het voorbeeldmenu of kies eigen foto’s. Daarna maakt Studio één vierkante compositie.</p>
      </div>
      <p class="next-action">{{ nextAction() }}</p>
    </header>

    <div class="workflow-grid">
      <aside class="step-rail" aria-label="Stappen">
        <ol class="monitor-steps">
          @for (step of monitorSteps(); track step.label) {
            <li [class]="step.state">
              <strong>{{ step.label }}</strong>
              <span>{{ step.detail }}</span>
            </li>
          }
        </ol>
      </aside>

      <section class="action-panel" aria-label="Volgende actie">
        <div class="task-heading">
          <p class="eyebrow">Snel starten</p>
          <h2>Gebruik het voorbeeldmenu</h2>
          <p>Laadt direct burger, drank en friet. Geen instellingen nodig om de eerste generatie te testen.</p>
        </div>

        <button
          class="example-menu"
          type="button"
          (click)="onUseExampleMenu()"
        >Gebruik voorbeeldmenu</button>

        <div class="example-strip" aria-label="Voorbeeldbeelden">
          @for (exampleImage of exampleImages; track exampleImage.name) {
            <figure>
              <img
                [src]="exampleImage.url"
                [alt]="exampleImage.label"
              />
              <figcaption>{{ exampleImage.label }}</figcaption>
            </figure>
          }
        </div>

        <div class="upload-card">
          <label>
            <input
              type="file"
              accept="image/*"
              multiple
              (change)="onFilesSelected($event)"
            />
            <span>Foto’s kiezen</span>
            <small>{{ selectedImageCountLabel() }}</small>
          </label>

          <label>
            <input
              type="file"
              accept="image/*"
              multiple
              webkitdirectory
              (change)="onFilesSelected($event)"
            />
            <span>Map kiezen</span>
            <small>Meerdere foto’s tegelijk</small>
          </label>
        </div>

        <div class="controls" aria-label="Transformatie instellingen">
          <label>
            Stijl
            <select
              [ngModel]="preset()"
              (ngModelChange)="preset.set($event)"
            >
              <option value="studio">Witte menu achtergrond</option>
              <option value="food">Warme horeca sfeer</option>
              <option value="retail">Winkelpresentatie</option>
              <option value="premium">Luxe campagnebeeld</option>
            </select>
          </label>

          <label>
            Formaat
            <select
              [ngModel]="ratio()"
              (ngModelChange)="ratio.set($event)"
            >
              <option value="16:9">Breed scherm</option>
              <option value="9:16">Staand scherm</option>
              <option value="1:1">Vierkant beeld</option>
            </select>
          </label>

          <label class="prompt-field">
            Instructie
            <textarea
              [ngModel]="prompt()"
              (ngModelChange)="prompt.set($event)"
              rows="2"
            ></textarea>
          </label>

          <button
            class="primary"
            type="button"
            [disabled]="!hasImages() || isGenerating()"
            (click)="onGenerateBatch()"
          >
            {{ isGenerating() ? 'Beelden maken...' : 'Maak nieuwe beelden' }}
          </button>
        </div>
      </section>

      <aside class="proof-panel" aria-label="Status en bewijs">
        <p class="eyebrow">Status</p>
        <h2>{{ monitor().message }}</h2>
        <div class="progress-block">
          <div class="progress-meta">
            <strong>{{ progressLabel() }}</strong>
            <span>{{ estimateLabel() }}</span>
          </div>
          <div class="progress-track" aria-label="Voortgang">
            <span [style.width.%]="monitor().progress"></span>
          </div>
        </div>
        <dl>
          <div>
            <dt>Beelden</dt>
            <dd>{{ selectedImageCountLabel() }}</dd>
          </div>
          <div>
            <dt>Referentie</dt>
            <dd>{{ monitor().jobId }}</dd>
          </div>
          <div>
            <dt>Systeem</dt>
            <dd>{{ monitor().provider }}</dd>
          </div>
        </dl>

        <ol class="activity-list">
          @for (event of monitor().events.slice(-4); track event) {
            <li>{{ event }}</li>
          }
        </ol>
      </aside>
    </div>
  </section>

  @if (generationError(); as error) {
    <p class="status-message">{{ error }}</p>
  }

  @if (hasGeneratedResult()) {
    <section class="image-grid" aria-label="Resultaat">
    @for (image of resultImages(); track image.id) {
      <article class="image-card">
        <header>
          <div>
            <h2>{{ image.name }}</h2>
            <p>{{ image.size }} · {{ ratio() }}</p>
          </div>
          <button class="ghost" type="button" (click)="onUseExampleMenu()">Opnieuw starten</button>
        </header>

        <div class="preview-pair">
          <figure>
            <img
              [src]="image.url"
              [alt]="image.name + ' origineel'"
            />
            <figcaption>Origineel</figcaption>
          </figure>
          <figure class="generated">
            <img
              [src]="image.previewUrl"
              [style.filter]="image.previewFilter"
              [alt]="image.name + ' variant'"
            />
            <figcaption>{{ image.selectedVariantData.label }}</figcaption>
          </figure>
        </div>

        <p class="note">{{ image.note }}</p>
      </article>
    }
  </section>
  }
</main>