diff --git a/src/app/pages/recipe-upload-page/recipe-upload-page.html b/src/app/pages/recipe-upload-page/recipe-upload-page.html
index 01e5643..37390b5 100644
--- a/src/app/pages/recipe-upload-page/recipe-upload-page.html
+++ b/src/app/pages/recipe-upload-page/recipe-upload-page.html
@@ -16,7 +16,7 @@
} @else if (displayStep() === RecipeUploadStep.ENTER_DATA) {
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/EnterRecipeDataSubmitEvent.ts b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/EnterRecipeDataSubmitEvent.ts
index a7fbc6e..bbe05fd 100644
--- a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/EnterRecipeDataSubmitEvent.ts
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/EnterRecipeDataSubmitEvent.ts
@@ -2,9 +2,9 @@ export interface EnterRecipeDataSubmitEvent {
title: string;
slug: string;
ingredients: Array<{
- amount: string | null;
+ amount?: string | null;
name: string;
- notes: string | null;
+ notes?: string | null;
}>;
rawText: string;
}
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.css b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.css
index e84c155..f0915a6 100644
--- a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.css
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.css
@@ -1,11 +1,3 @@
-.ingredients-table {
- width: 100ch;
-}
-
-.ingredient-input {
- width: 100%;
-}
-
form {
display: flex;
flex-direction: column;
@@ -20,6 +12,21 @@ textarea {
}
.draft-info-container {
+ width: 60ch;
display: flex;
- column-gap: 10px;
+ justify-content: space-between;
+}
+
+.draft-actions-button {
+ padding: 0;
+}
+
+.mat-column-reorder {
+ width: 32px;
+ text-align: center;
+}
+
+.mat-column-actions {
+ width: 32px;
+ text-align: center;
}
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.html b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.html
index 3ba338f..d99ab15 100644
--- a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.html
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/enter-recipe-data.html
@@ -1,11 +1,11 @@
-
Draft started: {{ model().draft!.created }}
-
Last saved: {{ model().draft!.modified }}
+
Draft started: {{ draft().created | date: "short" }}
+
Last saved: {{ draft().modified | date: "short" }}
-
-
+
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/image-upload-dialog/image-upload-dialog.ts b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/image-upload-dialog/image-upload-dialog.ts
index a0833ad..124666c 100644
--- a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/image-upload-dialog/image-upload-dialog.ts
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/image-upload-dialog/image-upload-dialog.ts
@@ -10,6 +10,7 @@ import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angula
import { MatCheckbox } from '@angular/material/checkbox';
import { MatDialogRef } from '@angular/material/dialog';
import { ImageDoesNotExistValidator } from '../../../../../shared/validators/image-does-not-exist-validator';
+import { DialogContainer } from '../../../../../shared/components/dialog-container/dialog-container';
@Component({
selector: 'app-image-upload-dialog',
@@ -23,6 +24,7 @@ import { ImageDoesNotExistValidator } from '../../../../../shared/validators/ima
ReactiveFormsModule,
MatCheckbox,
MatError,
+ DialogContainer,
],
templateUrl: './image-upload-dialog.html',
styleUrl: './image-upload-dialog.css',
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.css b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.css
new file mode 100644
index 0000000..b9cb93b
--- /dev/null
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.css
@@ -0,0 +1,5 @@
+form {
+ display: flex;
+ flex-direction: column;
+ row-gap: 10px;
+}
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.html b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.html
new file mode 100644
index 0000000..576b3d8
--- /dev/null
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.html
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.spec.ts b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.spec.ts
new file mode 100644
index 0000000..b04dd01
--- /dev/null
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { IngredientDialog } from './ingredient-dialog';
+
+describe('IngredientDialog', () => {
+ let component: IngredientDialog;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [IngredientDialog],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(IngredientDialog);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.ts b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.ts
new file mode 100644
index 0000000..87e8402
--- /dev/null
+++ b/src/app/pages/recipe-upload-page/steps/enter-recipe-data/ingredient-dialog/ingredient-dialog.ts
@@ -0,0 +1,44 @@
+import { Component, inject, OnInit } from '@angular/core';
+import { DialogContainer } from '../../../../../shared/components/dialog-container/dialog-container';
+import { MatFormField, MatInput, MatLabel } from '@angular/material/input';
+import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
+import { MatButton } from '@angular/material/button';
+import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
+import { IngredientDraftClientModel } from '../../../../../shared/client-models/IngredientDraftClientModel';
+
+@Component({
+ selector: 'app-ingredient-dialog',
+ imports: [DialogContainer, MatFormField, MatLabel, MatInput, ReactiveFormsModule, MatButton],
+ templateUrl: './ingredient-dialog.html',
+ styleUrl: './ingredient-dialog.css',
+})
+export class IngredientDialog implements OnInit {
+ public readonly dialogRef = inject(MatDialogRef);
+ private readonly model = inject(MAT_DIALOG_DATA);
+
+ protected readonly ingredientForm = new FormGroup({
+ amount: new FormControl(''),
+ name: new FormControl('', Validators.required),
+ notes: new FormControl(''),
+ });
+
+ public ngOnInit(): void {
+ this.ingredientForm.patchValue({
+ amount: this.model.draft.amount,
+ name: this.model.draft.name,
+ notes: this.model.draft.notes,
+ });
+ }
+
+ protected onSubmit(event: SubmitEvent): void {
+ event.preventDefault();
+ this.dialogRef.close({
+ ...this.model,
+ draft: {
+ amount: this.ingredientForm.value.amount,
+ name: this.ingredientForm.value.name,
+ notes: this.ingredientForm.value.notes,
+ },
+ });
+ }
+}
diff --git a/src/app/shared/client-models/IngredientDraftClientModel.ts b/src/app/shared/client-models/IngredientDraftClientModel.ts
new file mode 100644
index 0000000..6fb7a4d
--- /dev/null
+++ b/src/app/shared/client-models/IngredientDraftClientModel.ts
@@ -0,0 +1,6 @@
+import { IngredientDraft } from '../models/RecipeDraftView.model';
+
+export interface IngredientDraftClientModel {
+ id: number;
+ draft: IngredientDraft;
+}
diff --git a/src/app/shared/components/dialog-container/dialog-container.css b/src/app/shared/components/dialog-container/dialog-container.css
new file mode 100644
index 0000000..0ef2a90
--- /dev/null
+++ b/src/app/shared/components/dialog-container/dialog-container.css
@@ -0,0 +1,6 @@
+.dialog-container {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ row-gap: 10px;
+}
diff --git a/src/app/shared/components/dialog-container/dialog-container.html b/src/app/shared/components/dialog-container/dialog-container.html
new file mode 100644
index 0000000..7836b8f
--- /dev/null
+++ b/src/app/shared/components/dialog-container/dialog-container.html
@@ -0,0 +1,4 @@
+
+
{{ title() }}
+
+
diff --git a/src/app/shared/components/dialog-container/dialog-container.spec.ts b/src/app/shared/components/dialog-container/dialog-container.spec.ts
new file mode 100644
index 0000000..c799e73
--- /dev/null
+++ b/src/app/shared/components/dialog-container/dialog-container.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DialogContainer } from './dialog-container';
+
+describe('DialogContainer', () => {
+ let component: DialogContainer;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [DialogContainer],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(DialogContainer);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/components/dialog-container/dialog-container.ts b/src/app/shared/components/dialog-container/dialog-container.ts
new file mode 100644
index 0000000..b9b1d95
--- /dev/null
+++ b/src/app/shared/components/dialog-container/dialog-container.ts
@@ -0,0 +1,11 @@
+import { Component, input } from '@angular/core';
+
+@Component({
+ selector: 'app-dialog-container',
+ imports: [],
+ templateUrl: './dialog-container.html',
+ styleUrl: './dialog-container.css',
+})
+export class DialogContainer {
+ public readonly title = input.required();
+}