Skip to content

Commit d9d0627

Browse files
feat: Add comprehensive backend modules for booking, inventory, and partnership, along with frontend veil management features.
1 parent 4ae0dff commit d9d0627

11 files changed

Lines changed: 125 additions & 89 deletions

File tree

62 KB
Loading

frontend/src/entities/veil/veil.model.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ export interface Veil {
44
description?: string;
55
price: number;
66
rentalPrice?: number;
7-
// Backend has images[], frontend currently uses single image in some places,
8-
// but we should support array.
97
images: string[];
108
category: string;
119
isAvailable: boolean;
12-
sku?: string;
13-
silhouette?: string;
14-
neckline?: string;
15-
fabric?: string;
16-
trainLength?: string;
17-
stock?: number;
10+
sku: string;
11+
silhouette: string;
12+
neckline: string;
13+
fabric: string;
14+
trainLength: string;
15+
stock: number;
1816
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<div
2+
class="bg-white rounded-2xl p-6 shadow-[0_4px_6px_-1px_rgba(0,0,0,0.05)] hover:shadow-[0_4px_20px_-2px_rgba(0,0,0,0.05)] transition-all duration-300 group relative reveal-item"
3+
[style.animation-delay.ms]="index() * 100"
4+
>
5+
<!-- Top Section: Image & Price -->
6+
<div class="flex justify-between items-start mb-6 relative">
7+
<div
8+
class="w-20 h-20 rounded-full overflow-hidden border-2 border-white shadow-md cursor-pointer"
9+
(click)="onViewImage()"
10+
>
11+
<img
12+
[src]="safeImageUrl()"
13+
[alt]="veil().name"
14+
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
15+
/>
16+
</div>
17+
<span class="font-serif text-xl font-bold text-gray-900"
18+
>{{ veil().price }} TJS</span
19+
>
20+
<div
21+
class="absolute -top-4 -right-4 w-24 h-24 bg-primary/5 rounded-full blur-2xl pointer-events-none"
22+
></div>
23+
</div>
24+
<div class="mb-6">
25+
<h3 class="text-2xl font-serif text-gray-900 mb-1">{{ veil().name }}</h3>
26+
<p class="text-xs tracking-wider text-gray-500 uppercase font-medium">
27+
{{ veil().sku }}
28+
</p>
29+
</div>
30+
<div class="bg-gray-50 rounded-xl p-5 mb-6 space-y-3">
31+
<div
32+
class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0"
33+
>
34+
<span class="text-gray-500">Silhouette</span>
35+
<span class="font-semibold font-serif text-gray-900">{{
36+
veil().silhouette
37+
}}</span>
38+
</div>
39+
<div
40+
class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0"
41+
>
42+
<span class="text-gray-500">Neckline</span>
43+
<span class="font-semibold font-serif text-gray-900">{{
44+
veil().neckline
45+
}}</span>
46+
</div>
47+
<div
48+
class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0"
49+
>
50+
<span class="text-gray-500">Fabric</span>
51+
<span class="font-semibold font-serif text-gray-900">{{
52+
veil().fabric
53+
}}</span>
54+
</div>
55+
<div class="flex justify-between items-center text-sm">
56+
<span class="text-gray-500">Train Length</span>
57+
<span class="font-semibold font-serif text-gray-900">{{
58+
veil().trainLength
59+
}}</span>
60+
</div>
61+
</div>
62+
63+
<!-- Footer: Status & Action -->
64+
<div class="flex items-center justify-between pt-2">
65+
<div class="flex items-center gap-2">
66+
<span
67+
class="w-2.5 h-2.5 rounded-full"
68+
[class]="
69+
veil().stock > 0
70+
? 'bg-green-500 ' + (veil().stock > 1 ? 'animate-pulse' : '')
71+
: 'bg-yellow-500'
72+
"
73+
></span>
74+
<span class="text-sm font-medium text-gray-900">
75+
@if (veil().stock > 0) {
76+
<ng-container i18n="@@veilAvailable"
77+
>{{ veil().stock }} Available</ng-container
78+
>
79+
} @else {
80+
<ng-container i18n="@@veilOutOfStock">Out of Stock</ng-container>
81+
}
82+
</span>
83+
</div>
84+
<button
85+
(click)="onEdit()"
86+
class="flex items-center gap-1 text-primary hover:text-primary-hover transition-colors text-sm font-medium group-hover:translate-x-1 transition-transform"
87+
>
88+
<span class="material-symbols-outlined text-base">edit</span>
89+
<span i18n="@@veilAdminEdit">Edit</span>
90+
</button>
91+
</div>
92+
</div>

frontend/src/pages/veil/ui/veil-card/veil-card.component.scss

Whitespace-only changes.

frontend/src/pages/veil/ui/veil-card/veil-card.component.ts

Lines changed: 3 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,14 @@
11
import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
22
import { CommonModule, NgOptimizedImage } from '@angular/common';
3-
import { Veil } from '@pages/veil/veil.interface';
3+
import { Veil } from '@entities/veil/veil.model';
44

55
@Component({
66
selector: 'app-veil-card',
77
standalone: true,
88
imports: [CommonModule, NgOptimizedImage],
99
changeDetection: ChangeDetectionStrategy.OnPush,
10-
template: `
11-
<div class="bg-white rounded-2xl p-6 shadow-[0_4px_6px_-1px_rgba(0,0,0,0.05)] hover:shadow-[0_4px_20px_-2px_rgba(0,0,0,0.05)] transition-all duration-300 group relative reveal-item" [style.animation-delay.ms]="index() * 100">
12-
13-
<!-- Top Section: Image & Price -->
14-
<div class="flex justify-between items-start mb-6 relative">
15-
<div class="w-20 h-20 rounded-full overflow-hidden border-2 border-white shadow-md cursor-pointer" (click)="onViewImage()">
16-
<img [src]="safeImageUrl()" [alt]="veil().name" class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500">
17-
</div>
18-
<span class="font-serif text-xl font-bold text-gray-900">{{ veil().price }} TJS</span>
19-
<!-- Decorative Blur Effect -->
20-
<div class="absolute -top-4 -right-4 w-24 h-24 bg-primary/5 rounded-full blur-2xl pointer-events-none"></div>
21-
</div>
22-
23-
<!-- Title & SKU -->
24-
<div class="mb-6">
25-
<h3 class="text-2xl font-serif text-gray-900 mb-1">{{ veil().name }}</h3>
26-
<p class="text-xs tracking-wider text-gray-500 uppercase font-medium">{{ veil().sku }}</p>
27-
</div>
28-
29-
<!-- Attributes Box -->
30-
<div class="bg-gray-50 rounded-xl p-5 mb-6 space-y-3">
31-
<div class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0">
32-
<span class="text-gray-500">Silhouette</span>
33-
<span class="font-semibold font-serif text-gray-900">{{ veil().silhouette }}</span>
34-
</div>
35-
<div class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0">
36-
<span class="text-gray-500">Neckline</span>
37-
<span class="font-semibold font-serif text-gray-900">{{ veil().neckline }}</span>
38-
</div>
39-
<div class="flex justify-between items-center text-sm border-b border-gray-100 pb-2 last:border-0 last:pb-0">
40-
<span class="text-gray-500">Fabric</span>
41-
<span class="font-semibold font-serif text-gray-900">{{ veil().fabric }}</span>
42-
</div>
43-
<div class="flex justify-between items-center text-sm">
44-
<span class="text-gray-500">Train Length</span>
45-
<span class="font-semibold font-serif text-gray-900">{{ veil().trainLength }}</span>
46-
</div>
47-
</div>
48-
49-
<!-- Footer: Status & Action -->
50-
<div class="flex items-center justify-between pt-2">
51-
<div class="flex items-center gap-2">
52-
<span class="w-2.5 h-2.5 rounded-full" [class]="veil().stock > 0 ? 'bg-green-500 ' + (veil().stock > 1 ? 'animate-pulse' : '') : 'bg-yellow-500'"></span>
53-
<span class="text-sm font-medium text-gray-900">
54-
@if (veil().stock > 0) {
55-
<ng-container i18n="@@veilAvailable">{{ veil().stock }} Available</ng-container>
56-
} @else {
57-
<ng-container i18n="@@veilOutOfStock">Out of Stock</ng-container>
58-
}
59-
</span>
60-
</div>
61-
<button (click)="onEdit()" class="flex items-center gap-1 text-primary hover:text-primary-hover transition-colors text-sm font-medium group-hover:translate-x-1 transition-transform">
62-
<span class="material-symbols-outlined text-base">edit</span>
63-
<span i18n="@@veilAdminEdit">Edit</span>
64-
</button>
65-
</div>
66-
67-
</div>
68-
`
10+
templateUrl: './veil-card.component.html',
11+
styleUrl: './veil-card.component.scss'
6912
})
7013
export class VeilCardComponent {
7114
veil = input.required<Veil>();
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Veil } from "@entities/veil/veil.model";
2+
3+
export const veilFormData:Veil = {
4+
id: "lorem",
5+
name: 'Just Name of Veil',
6+
sku: 'lorem',
7+
price: 2500,
8+
stock: 10,
9+
images: [],
10+
silhouette: 'lorem',
11+
neckline: 'lorem',
12+
fabric: 'lorem',
13+
trainLength: 'lorem',
14+
category: 'lorem',
15+
isAvailable: true,
16+
description: 'lorem'
17+
}

frontend/src/pages/veil/ui/veil-form/veil-form.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Component, input, output, ChangeDetectionStrategy, inject, signal, effect } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
4-
import { Veil } from '@pages/veil/veil.interface';
4+
import { Veil } from '@entities/veil/veil.model';
5+
import { veilFormData } from '@pages/veil/ui/veil-form/veil-form.component.data';
56

67
@Component({
78
selector: 'app-veil-form',
@@ -14,6 +15,7 @@ export class VeilFormComponent {
1415
veil = input<Veil | null>(null);
1516
save = output<{ data: any, file: File | null }>();
1617
cancel = output<void>();
18+
veilModel = signal<Veil>(veilFormData);
1719

1820
private fb = inject(FormBuilder);
1921
veilForm!: FormGroup;

frontend/src/pages/veil/ui/veil-item/veil-item.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component, input, output, computed } from '@angular/core';
22
import { CommonModule } from '@angular/common';
3-
import { Veil } from '@pages/veil/veil.interface';
3+
import { Veil } from '@entities/veil/veil.model';
44

55
@Component({
66
selector: 'app-veil-item',

frontend/src/pages/veil/ui/veil-modal/veil-modal.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Component, input, output, signal, effect, computed } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import { FormsModule } from '@angular/forms';
4-
import { Veil } from '@pages/veil/veil.interface';
4+
import { Veil } from '@entities/veil/veil.model';
55

66
@Component({
77
selector: 'app-veil-modal',

frontend/src/pages/veil/veil.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Component, ChangeDetectionStrategy, signal, inject, OnInit } from '@angular/core';
21
import { CommonModule } from '@angular/common';
3-
import { VeilService } from '../../entities/veil/veil.service';
2+
import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';
43
import { Veil } from '../../entities/veil/veil.model';
4+
import { VeilService } from '../../entities/veil/veil.service';
55
import { VeilCardComponent } from './ui/veil-card/veil-card.component';
66
import { VeilFormComponent } from './ui/veil-form/veil-form.component';
77

0 commit comments

Comments
 (0)