diff --git a/src/app/app.html b/src/app/app.html
index 47869cd..b6a87ba 100644
--- a/src/app/app.html
+++ b/src/app/app.html
@@ -1,3 +1,7 @@
-
-
-
+
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index d948d53..4e4ce05 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -12,4 +12,10 @@ export const routes: Routes = [
path: "",
loadChildren: () => import("./features/auth/auth.routes").then((routes) => routes.AuthRoutes),
},
+ {
+ path: "products",
+ loadChildren: () =>
+ import("./features/product/product.routes").then((routes) => routes.productRoutes),
+ // canActivate: [authGuard]
+ },
];
diff --git a/src/app/features/product/add-product/add-product.css b/src/app/features/product/add-product/add-product.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/features/product/add-product/add-product.html b/src/app/features/product/add-product/add-product.html
new file mode 100644
index 0000000..665ea7b
--- /dev/null
+++ b/src/app/features/product/add-product/add-product.html
@@ -0,0 +1,86 @@
+
diff --git a/src/app/features/product/add-product/add-product.spec.ts b/src/app/features/product/add-product/add-product.spec.ts
new file mode 100644
index 0000000..6f894c3
--- /dev/null
+++ b/src/app/features/product/add-product/add-product.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { AddProduct } from "./add-product";
+
+describe("AddProduct", () => {
+ let component: AddProduct;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [AddProduct],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(AddProduct);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/product/add-product/add-product.ts b/src/app/features/product/add-product/add-product.ts
new file mode 100644
index 0000000..2417641
--- /dev/null
+++ b/src/app/features/product/add-product/add-product.ts
@@ -0,0 +1,41 @@
+import { Component, ElementRef, signal, ViewChild } from "@angular/core";
+import { ReactiveFormsModule } from "@angular/forms";
+import { ImageInput } from "../../../shared/components/image-input/image-input";
+
+export interface ImageSelection {
+ id: string;
+ url: string;
+ file: File;
+}
+
+@Component({
+ selector: "app-add-product",
+ imports: [ReactiveFormsModule, ImageInput],
+ templateUrl: "./add-product.html",
+ styleUrl: "./add-product.css",
+})
+export class AddProduct {
+ @ViewChild("imageDialog") imageDialog!: ElementRef;
+ activeImage = signal(null);
+ selectedImages = signal>({});
+
+ openPreview(image: ImageSelection) {
+ this.activeImage.set(image);
+ this.imageDialog.nativeElement.showModal();
+ }
+
+ confirmImage() {
+ // Add the current image to the selected images
+ const current = this.activeImage();
+ if (current) {
+ this.selectedImages.update((images) => ({ ...images, [current.id]: current }));
+ }
+ console.log(this.selectedImages());
+ this.closeDialog();
+ }
+
+ closeDialog() {
+ this.activeImage.set(null);
+ this.imageDialog.nativeElement.close();
+ }
+}
diff --git a/src/app/features/product/product.css b/src/app/features/product/product.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/features/product/product.html b/src/app/features/product/product.html
new file mode 100644
index 0000000..772b623
--- /dev/null
+++ b/src/app/features/product/product.html
@@ -0,0 +1 @@
+product works!
diff --git a/src/app/features/product/product.routes.ts b/src/app/features/product/product.routes.ts
new file mode 100644
index 0000000..c11716c
--- /dev/null
+++ b/src/app/features/product/product.routes.ts
@@ -0,0 +1,9 @@
+import { Routes } from "@angular/router";
+import { AddProduct } from "./add-product/add-product";
+
+export const productRoutes: Routes = [
+ {
+ path: "create",
+ component: AddProduct,
+ },
+];
diff --git a/src/app/features/product/product.spec.ts b/src/app/features/product/product.spec.ts
new file mode 100644
index 0000000..8a5b60f
--- /dev/null
+++ b/src/app/features/product/product.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { Product } from "./product";
+
+describe("Product", () => {
+ let component: Product;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [Product],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(Product);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/features/product/product.ts b/src/app/features/product/product.ts
new file mode 100644
index 0000000..9c169a0
--- /dev/null
+++ b/src/app/features/product/product.ts
@@ -0,0 +1,9 @@
+import { Component } from "@angular/core";
+
+@Component({
+ selector: "app-product",
+ imports: [],
+ templateUrl: "./product.html",
+ styleUrl: "./product.css",
+})
+export class Product {}
diff --git a/src/app/shared/components/image-input/image-input.css b/src/app/shared/components/image-input/image-input.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/shared/components/image-input/image-input.html b/src/app/shared/components/image-input/image-input.html
new file mode 100644
index 0000000..5145705
--- /dev/null
+++ b/src/app/shared/components/image-input/image-input.html
@@ -0,0 +1,29 @@
+
diff --git a/src/app/shared/components/image-input/image-input.spec.ts b/src/app/shared/components/image-input/image-input.spec.ts
new file mode 100644
index 0000000..14e3aec
--- /dev/null
+++ b/src/app/shared/components/image-input/image-input.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from "@angular/core/testing";
+
+import { ImageInput } from "./image-input";
+
+describe("ImageInput", () => {
+ let component: ImageInput;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [ImageInput],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(ImageInput);
+ component = fixture.componentInstance;
+ await fixture.whenStable();
+ });
+
+ it("should create", () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/shared/components/image-input/image-input.ts b/src/app/shared/components/image-input/image-input.ts
new file mode 100644
index 0000000..027cab3
--- /dev/null
+++ b/src/app/shared/components/image-input/image-input.ts
@@ -0,0 +1,26 @@
+import { Component, EventEmitter, Input, Output } from "@angular/core";
+import { Camera, LucideAngularModule } from "lucide-angular";
+import { ImageSelection } from "../../../features/product/add-product/add-product";
+
+@Component({
+ selector: "app-image-input",
+ imports: [LucideAngularModule],
+ templateUrl: "./image-input.html",
+ styleUrl: "./image-input.css",
+})
+export class ImageInput {
+ cameraIcon = Camera;
+
+ @Output() imageSelected = new EventEmitter();
+ @Input() id!: string;
+ @Input() bgImageUrl: string | undefined;
+
+ handleFileSelect(event: Event) {
+ const input = event.target as HTMLInputElement;
+ if (input.files && input.files[0]) {
+ const file = input.files[0];
+ const url = URL.createObjectURL(file);
+ this.imageSelected.emit({ id: this.id, url: url, file: file });
+ }
+ }
+}
diff --git a/src/styles.css b/src/styles.css
index 9123e1d..b38fa58 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -13,7 +13,7 @@
}
body {
- @apply bg-gray-100;
+ @apply bg-gray-100 antialiased m-0;
}
.wrapper {
@@ -21,7 +21,7 @@ body {
}
.btn {
- @apply rounded-full transition-all duration-200 font-medium ease-out flex justify-center active:translate-y-px disabled:opacity-50 disabled:cursor-not-allowed;
+ @apply rounded-xl py-2 transition-all duration-200 font-medium ease-out flex justify-center active:translate-y-px disabled:opacity-50 disabled:cursor-not-allowed;
}
.btn-ghost {
@@ -39,6 +39,7 @@ body {
.fieldset {
@apply space-y-1;
}
+
.fieldset-legend {
@apply text-xs font-bold ml-2 text-gray-800;
}
@@ -51,6 +52,14 @@ body {
@apply p-3 border border-gray-300 rounded-xl text-sm w-full;
}
+.input-image {
+ @apply rounded-xl border bg-teal-100 border-teal-500 border-dashed;
+}
+
+.input-image-ghost {
+ @apply bg-gray-100 border-gray-300;
+}
+
.dropdown {
position-area: span-left bottom;
@apply p-4 mt-2 border border-gray-300 shadow-lg rounded-xl space-y-2 text-gray-800;
@@ -59,3 +68,16 @@ body {
.dropdown li {
@apply rounded-lg hover:bg-linear-to-r hover:from-teal-300 hover:to-transparent px-5 py-1;
}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ @apply font-space text-gray-800;
+}
+
+h1 {
+ @apply text-3xl my-4 ml-2;
+}