create light bottomsheet drawer for gold payload
This commit is contained in:
+3
-3
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"$schema": "./node_modules/@angular/service-worker/config/schema.json",
|
||||
"appData": {
|
||||
"appVersion": "0.0.4",
|
||||
"buildDate": "2026-05-11T16:11:59.783Z",
|
||||
"buildNumber": 4
|
||||
"appVersion": "0.0.9",
|
||||
"buildDate": "2026-05-13T06:42:17.700Z",
|
||||
"buildNumber": 9
|
||||
},
|
||||
"assetGroups": [
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<shared-dialog
|
||||
<shared-light-bottomsheet
|
||||
[(visible)]="visible"
|
||||
[header]="preparedTitle()"
|
||||
[modal]="true"
|
||||
[style]="{ width: '500px' }"
|
||||
[style]="{ 'max-height': '90svh', height: 'auto' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
@@ -18,4 +18,4 @@
|
||||
/>
|
||||
}
|
||||
}
|
||||
</shared-dialog>
|
||||
</shared-light-bottomsheet>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IGoodResponse } from '@/domains/pos/models/good.io';
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component';
|
||||
import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core';
|
||||
import { IGoldPayload, IPosOrderItem, IStandardPayload, TPosOrderGoodPayload } from '../models';
|
||||
import { PosLandingStore } from '../store/main.store';
|
||||
@@ -10,7 +10,7 @@ import { PosStandardPayloadFormComponent } from './payloads/standard/form.compon
|
||||
@Component({
|
||||
selector: 'pos-payload-form-dialog',
|
||||
templateUrl: './payload-form.component.html',
|
||||
imports: [PosGoldPayloadFormComponent, SharedDialogComponent, PosStandardPayloadFormComponent],
|
||||
imports: [PosGoldPayloadFormComponent, SharedLightBottomsheetComponent, PosStandardPayloadFormComponent],
|
||||
})
|
||||
export class PayloadFormDialogComponent extends AbstractDialog {
|
||||
@Input({ required: true }) good!: IGoodResponse;
|
||||
|
||||
@@ -1,69 +1,67 @@
|
||||
@if (formVisible()) {
|
||||
<div class="form-group">
|
||||
<form [formGroup]="form">
|
||||
<app-input [control]="form.controls.unit_price" name="unit_price" label="قیمت پایه هر گرم" type="price" />
|
||||
<app-input [control]="form.controls.quantity" name="quantity" label="مقدار" type="number" suffix="گرم" />
|
||||
<app-enum-select [control]="form.controls.payload.controls.karat" type="goldKarat" name="karat" />
|
||||
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.payload.controls.wages_percentage"
|
||||
[amountControl]="form.controls.payload.controls.wages_amount"
|
||||
[baseAmount]="unitWithQuantity()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="unitWithQuantity()"
|
||||
name="wages"
|
||||
label="اجرت"
|
||||
/>
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.payload.controls.commission_percentage"
|
||||
[amountControl]="form.controls.payload.controls.commission_amount"
|
||||
[baseAmount]="unitWithQuantity()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="unitWithQuantity()"
|
||||
name="commission"
|
||||
label="حقالعمل"
|
||||
/>
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.payload.controls.profit_percentage"
|
||||
[amountControl]="form.controls.payload.controls.profit_amount"
|
||||
[baseAmount]="totalAmountBeforeProfit()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="totalAmountBeforeProfit()"
|
||||
name="profit"
|
||||
label="سود"
|
||||
/>
|
||||
</form>
|
||||
<div class="form-group">
|
||||
<form [formGroup]="form">
|
||||
<app-input [control]="form.controls.unit_price" name="unit_price" label="قیمت پایه هر گرم" type="price" />
|
||||
<app-input [control]="form.controls.quantity" name="quantity" label="مقدار" type="number" suffix="گرم" />
|
||||
<app-enum-select [control]="form.controls.payload.controls.karat" type="goldKarat" name="karat" />
|
||||
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.discount_percentage"
|
||||
[amountControl]="form.controls.discount_amount"
|
||||
[baseAmount]="baseAmountForDiscountCalculation()"
|
||||
[percentageControl]="form.controls.payload.controls.wages_percentage"
|
||||
[amountControl]="form.controls.payload.controls.wages_amount"
|
||||
[baseAmount]="unitWithQuantity()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="baseAmountForDiscountCalculation()"
|
||||
name="discount"
|
||||
label="تخفیف"
|
||||
>
|
||||
<ng-template #labelSuffix>
|
||||
<p-selectButton
|
||||
[options]="discountTypeItems"
|
||||
[(ngModel)]="discountType"
|
||||
[allowEmpty]="false"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
(onChange)="changeDiscountCalculation($event)"
|
||||
/>
|
||||
</ng-template>
|
||||
</app-amount-percentage-input>
|
||||
[maxAmount]="unitWithQuantity()"
|
||||
name="wages"
|
||||
label="اجرت"
|
||||
/>
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.payload.controls.commission_percentage"
|
||||
[amountControl]="form.controls.payload.controls.commission_amount"
|
||||
[baseAmount]="unitWithQuantity()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="unitWithQuantity()"
|
||||
name="commission"
|
||||
label="حقالعمل"
|
||||
/>
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.payload.controls.profit_percentage"
|
||||
[amountControl]="form.controls.payload.controls.profit_amount"
|
||||
[baseAmount]="totalAmountBeforeProfit()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="totalAmountBeforeProfit()"
|
||||
name="profit"
|
||||
label="سود"
|
||||
/>
|
||||
</form>
|
||||
|
||||
<hr />
|
||||
<div class="flex flex-col gap-4 justify-center w-full">
|
||||
<pos-form-dialog-amount-card-template
|
||||
[totalAmount]="totalAmount()"
|
||||
[baseTotalAmount]="baseTotalAmount()"
|
||||
[discountAmount]="form.controls.discount_amount.value || 0"
|
||||
[taxAmount]="taxAmount()"
|
||||
<app-amount-percentage-input
|
||||
[percentageControl]="form.controls.discount_percentage"
|
||||
[amountControl]="form.controls.discount_amount"
|
||||
[baseAmount]="baseAmountForDiscountCalculation()"
|
||||
[minAmount]="0"
|
||||
[maxAmount]="baseAmountForDiscountCalculation()"
|
||||
name="discount"
|
||||
label="تخفیف"
|
||||
>
|
||||
<ng-template #labelSuffix>
|
||||
<p-selectButton
|
||||
[options]="discountTypeItems"
|
||||
[(ngModel)]="discountType"
|
||||
[allowEmpty]="false"
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
(onChange)="changeDiscountCalculation($event)"
|
||||
/>
|
||||
<button pButton class="sm:w-auto w-full" (click)="submit()">{{ preparedCTAText() }}</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-amount-percentage-input>
|
||||
|
||||
<hr />
|
||||
<div class="flex flex-col gap-4 justify-center w-full">
|
||||
<pos-form-dialog-amount-card-template
|
||||
[totalAmount]="totalAmount()"
|
||||
[baseTotalAmount]="baseTotalAmount()"
|
||||
[discountAmount]="form.controls.discount_amount.value || 0"
|
||||
[taxAmount]="taxAmount()"
|
||||
/>
|
||||
<button pButton class="sm:w-auto w-full" (click)="submit()">{{ preparedCTAText() }}</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,6 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
||||
baseAmountForDiscountCalculation = signal<number>(0);
|
||||
taxAmount = signal<number>(0);
|
||||
totalAmount = signal<number>(0);
|
||||
formVisible = signal<boolean>(false);
|
||||
|
||||
preparedCTAText = computed(() => (this.editMode ? 'اعمال ویرایش' : 'افزودن به لیست خرید'));
|
||||
|
||||
@@ -95,16 +94,6 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
||||
|
||||
form = this.initialForm();
|
||||
|
||||
override ngAfterViewInit(): void {
|
||||
setTimeout(() => {
|
||||
this.formVisible.set(true);
|
||||
if (this.editMode) {
|
||||
this.form.patchValue(this.initialValues || {}, { emitEvent: false });
|
||||
this.updateCalculateAmount(this.form.value as any);
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
override submitForm(payload: IPosOrderItem) {
|
||||
this.onSubmit.emit({
|
||||
...payload,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
type="button"
|
||||
pButton
|
||||
class="sticky! bottom-0 inset-x-0 w-full right-0 z-1200 border-t border-surface-border bg-surface-0 px-4 py-3 shadow-[0_-4px_16px_rgba(0,0,0,0.08)] md:hidden! rounded-b-none!"
|
||||
[style.paddingBottom]="'calc(0.75rem + env(safe-area-inset-bottom))'"
|
||||
[style.paddingBottom]="'calc(0.75rem + {{env(safe-area-inset-bottom)}})'"
|
||||
(click)="openInvoiceBottomSheet()"
|
||||
>
|
||||
<div class="mx-auto flex w-full max-w-3xl items-center justify-between">
|
||||
|
||||
@@ -36,7 +36,7 @@ export abstract class AbstractForm<
|
||||
return payload;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
ngOnInit() {
|
||||
this.form.reset(this.initialValues ?? this.defaultValues);
|
||||
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
||||
// console.log(key, control);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<div class="light-bottomsheet-mask" (click)="onMaskClick()"></div>
|
||||
|
||||
<section
|
||||
class="light-bottomsheet-panel"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
[attr.aria-hidden]="!visible"
|
||||
[ngStyle]="style || { 'max-height': mobileDrawerHeight, height: 'auto' }"
|
||||
>
|
||||
<div class="light-bottomsheet-content">
|
||||
@if (header || closable) {
|
||||
<header class="light-bottomsheet-header">
|
||||
<h3 class="light-bottomsheet-title">{{ header }}</h3>
|
||||
@if (closable) {
|
||||
<button type="button" class="light-bottomsheet-close" (click)="onVisibilityChange(false)" aria-label="Close">
|
||||
×
|
||||
</button>
|
||||
}
|
||||
</header>
|
||||
}
|
||||
<div class="p-4">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,120 @@
|
||||
import { NgStyle } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'shared-light-bottomsheet',
|
||||
templateUrl: './light-bottomsheet.component.html',
|
||||
imports: [NgStyle],
|
||||
styles: [
|
||||
`
|
||||
:host {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 11020;
|
||||
}
|
||||
|
||||
.light-bottomsheet-mask {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(15, 23, 42, 0.22);
|
||||
will-change: opacity;
|
||||
animation: sheetFadeIn var(--sheet-transition, 130ms cubic-bezier(0.2, 0, 0, 1));
|
||||
}
|
||||
|
||||
.light-bottomsheet-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
max-height: 80svh;
|
||||
background: var(--surface-card, #fff);
|
||||
border-radius: 12px 12px 0 0;
|
||||
box-shadow: none;
|
||||
transform: translate3d(0, 0, 0);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
animation: sheetSlideUp var(--sheet-transition, 130ms cubic-bezier(0.2, 0, 0, 1));
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.light-bottomsheet-content {
|
||||
max-height: 80svh;
|
||||
overflow: auto;
|
||||
padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.light-bottomsheet-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.light-bottomsheet-title {
|
||||
margin: 0;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.light-bottomsheet-close {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
padding: 0.25rem;
|
||||
line-height: 1;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
@keyframes sheetSlideUp {
|
||||
from {
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sheetFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`,
|
||||
],
|
||||
host: {
|
||||
'[style.display]': 'visible ? "block" : "none"',
|
||||
'[style.--sheet-transition]': 'transitionOptions',
|
||||
},
|
||||
})
|
||||
export class SharedLightBottomsheetComponent {
|
||||
@Input() header = '';
|
||||
@Input() visible = false;
|
||||
@Output() visibleChange = new EventEmitter<boolean>();
|
||||
|
||||
@Input() modal = true;
|
||||
@Input() closable = true;
|
||||
@Input() style: Record<string, string> | undefined;
|
||||
@Input() mobileDrawerHeight = '80svh';
|
||||
@Input() transitionOptions = '130ms cubic-bezier(0.2, 0, 0, 1)';
|
||||
|
||||
@Output() onHide = new EventEmitter<any>();
|
||||
|
||||
onVisibilityChange(nextValue: boolean) {
|
||||
this.visible = nextValue;
|
||||
this.visibleChange.emit(nextValue);
|
||||
if (!nextValue) {
|
||||
this.onHide.emit();
|
||||
}
|
||||
}
|
||||
|
||||
onMaskClick() {
|
||||
if (this.modal && this.closable) {
|
||||
this.onVisibilityChange(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user