Skip to content

Commit 1e78348

Browse files
committed
layout calculator
1 parent d4369d3 commit 1e78348

9 files changed

Lines changed: 511 additions & 260 deletions

src/app/components/calculator/calculator.component.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<div #calculatorContainer class="calculator" tabindex="-1">
2-
<div class="display">
2+
<div class="display" (dblclick)="selectAll()" [class.selected]="isSelected()">
33
<ng-container *ngIf="isMultiplying()">
44
<div class="multiply-label">
55
<span *ngIf="multiplyMode() === 'add'">{{
@@ -22,6 +22,13 @@
2222
<ng-container *ngIf="!isMultiplying()">
2323
<span class="display-value">{{ display() }}</span>
2424
</ng-container>
25+
<button
26+
class="select-all-btn"
27+
(click)="selectAll(); blurButton($event)"
28+
title="Select All"
29+
>
30+
<i class="fas fa-text-width"></i>
31+
</button>
2532
</div>
2633

2734
<div class="calculator-grid">

src/app/components/calculator/calculator.component.scss

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,25 @@
1818
justify-content: flex-end;
1919
box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.2);
2020
border-radius: $radius-3xl;
21+
position: relative;
22+
cursor: pointer;
23+
user-select: none;
24+
padding-right: 4rem;
25+
transition: all 0.3s ease;
26+
27+
&.selected {
28+
background: rgba($primary, 0.15);
29+
box-shadow:
30+
inset 0 2px 8px rgba(0, 0, 0, 0.2),
31+
0 0 0 2px rgba($primary, 0.5);
32+
animation: pulse-selection 1s ease-in-out infinite;
33+
34+
.display-value,
35+
.quantity-display {
36+
color: $primary;
37+
animation: text-pulse 1s ease-in-out infinite;
38+
}
39+
}
2140

2241
.multiply-label {
2342
font-size: 0.875rem;
@@ -30,6 +49,7 @@
3049
font-size: 2rem;
3150
font-weight: 700;
3251
color: $primary;
52+
transition: color 0.3s ease;
3353
}
3454

3555
.display-separator {
@@ -43,6 +63,42 @@
4363
color: var(--text-primary);
4464
word-break: break-all;
4565
text-align: right;
66+
flex: 1;
67+
transition: color 0.3s ease;
68+
}
69+
70+
.select-all-btn {
71+
position: absolute;
72+
right: $spacing-sm;
73+
top: 50%;
74+
transform: translateY(-50%);
75+
background: transparent;
76+
border: none;
77+
color: var(--text-secondary);
78+
font-size: 1rem;
79+
padding: $spacing-xs;
80+
cursor: pointer;
81+
border-radius: $radius-md;
82+
transition: all 0.2s ease;
83+
display: flex;
84+
align-items: center;
85+
justify-content: center;
86+
width: 32px;
87+
height: 32px;
88+
89+
&:hover {
90+
background: rgba(0, 0, 0, 0.1);
91+
color: $primary;
92+
transform: translateY(-50%) scale(1.1);
93+
}
94+
95+
&:active {
96+
transform: translateY(-50%) scale(0.95);
97+
}
98+
99+
i {
100+
font-size: 0.875rem;
101+
}
46102
}
47103
}
48104

@@ -195,3 +251,27 @@
195251
}
196252
}
197253
}
254+
255+
@keyframes pulse-selection {
256+
0%,
257+
100% {
258+
box-shadow:
259+
inset 0 2px 8px rgba(0, 0, 0, 0.2),
260+
0 0 0 2px rgba($primary, 0.5);
261+
}
262+
50% {
263+
box-shadow:
264+
inset 0 2px 8px rgba(0, 0, 0, 0.2),
265+
0 0 0 2px rgba($primary, 0.8);
266+
}
267+
}
268+
269+
@keyframes text-pulse {
270+
0%,
271+
100% {
272+
opacity: 1;
273+
}
274+
50% {
275+
opacity: 0.7;
276+
}
277+
}

src/app/components/calculator/calculator.component.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class CalculatorComponent implements AfterViewInit {
4545
isMultiplying = signal<boolean>(false);
4646
multiplyMode = signal<"add" | "update" | null>(null);
4747
pendingMultiplyValue = signal<number | null>(null);
48+
isSelected = signal<boolean>(false);
4849

4950
ngAfterViewInit(): void {
5051
setTimeout(() => this.focusCalculator(), 100);
@@ -63,16 +64,20 @@ export class CalculatorComponent implements AfterViewInit {
6364

6465
appendNumber(num: string): void {
6566
const current = this.display();
66-
if (current === "0") {
67+
if (current === "0" || this.isSelected()) {
6768
this.display.set(num);
69+
this.isSelected.set(false);
6870
} else {
6971
this.display.set(current + num);
7072
}
7173
}
7274

7375
appendDecimal(): void {
7476
const current = this.display();
75-
if (!current.includes(".")) {
77+
if (this.isSelected()) {
78+
this.display.set("0.");
79+
this.isSelected.set(false);
80+
} else if (!current.includes(".")) {
7681
this.display.set(current + ".");
7782
}
7883
}
@@ -180,4 +185,10 @@ export class CalculatorComponent implements AfterViewInit {
180185
handleMultiply(): void {
181186
this.multiplyItem();
182187
}
188+
189+
// Public method to select all display text
190+
selectAll(): void {
191+
// Mark text as selected - next input will replace
192+
this.isSelected.set(true);
193+
}
183194
}

src/app/components/cashier/cashier.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ <h3>
6363
</div>
6464

6565
<div class="items-list" *ngIf="items().length > 0; else noItems">
66-
<div class="item-row" *ngFor="let item of items()">
66+
<div
67+
class="item-row"
68+
*ngFor="let item of items()"
69+
[class.selected]="selectedItemId() === item.id"
70+
>
6771
<div class="item-actions">
6872
<button
6973
class="qty-btn decrease"

src/app/components/cashier/cashier.component.scss

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -302,40 +302,89 @@
302302
gap: 0;
303303
flex: 1;
304304
min-height: 0;
305+
max-height: 60vh;
305306
border: 1px solid $border-light;
306307
border-radius: 8px;
307-
overflow: hidden;
308+
position: relative;
309+
310+
// Custom scrollbar styling
311+
&::-webkit-scrollbar {
312+
width: 8px;
313+
}
314+
315+
&::-webkit-scrollbar-track {
316+
background: var(--bg-secondary);
317+
border-radius: 4px;
318+
}
319+
320+
&::-webkit-scrollbar-thumb {
321+
background: $primary;
322+
border-radius: 4px;
323+
transition: background 0.3s ease;
324+
325+
&:hover {
326+
background: darken($primary, 10%);
327+
}
328+
}
329+
330+
// Scroll indicator gradient at bottom
331+
&::after {
332+
content: "";
333+
position: sticky;
334+
bottom: 0;
335+
left: 0;
336+
right: 0;
337+
height: 40px;
338+
background: linear-gradient(
339+
to top,
340+
rgba(255, 255, 255, 0.95) 0%,
341+
rgba(255, 255, 255, 0.7) 50%,
342+
rgba(255, 255, 255, 0) 100%
343+
);
344+
pointer-events: none;
345+
z-index: 1;
346+
}
308347

309348
.item-row {
310349
display: flex;
311350
align-items: center;
312-
padding: 0.75rem 0.5rem;
351+
padding: 0.5rem 0.5rem;
313352
background: white;
314353
border-bottom: 1px solid $border-light;
315354
transition: all 0.2s;
316355
cursor: pointer;
317356
gap: 0.5rem;
357+
min-height: 60px;
318358

319359
&:hover {
320360
background: var(--bg-tertiary);
321361
}
322362

363+
&.selected {
364+
background: rgba($primary, 0.1);
365+
border-left: 3px solid $primary;
366+
padding-left: calc(0.5rem - 3px);
367+
368+
.item-info {
369+
font-weight: 500;
370+
}
371+
}
372+
323373
&:last-child {
324374
border-bottom: none;
325375
}
326376

327377
.item-info {
328378
display: flex;
329379
flex-direction: column;
330-
gap: 0.25rem;
380+
gap: 0.15rem;
331381
cursor: pointer;
332382
flex: 1;
333383
min-width: 0;
334384
padding: 0;
335385
border-radius: 0;
336386
transition: background 0.2s;
337387
position: relative;
338-
339388
&:hover {
340389
background: none;
341390
}
@@ -361,21 +410,21 @@
361410
gap: 0.25rem;
362411
order: -1;
363412
flex-wrap: wrap;
364-
margin-bottom: 0.25rem;
413+
margin-bottom: 0.15rem;
365414

366415
.item-quantity {
367-
font-size: 0.8rem;
416+
font-size: 0.75rem;
368417
font-weight: 600;
369418
color: var(--text-secondary);
370419
}
371420

372421
.item-unit-price {
373-
font-size: 0.7rem;
422+
font-size: 0.65rem;
374423
color: var(--text-muted);
375424
}
376425

377426
.item-price {
378-
font-size: 1rem;
427+
font-size: 0.95rem;
379428
font-weight: 700;
380429
color: var(--text-primary);
381430
margin-left: auto;
@@ -385,10 +434,10 @@
385434
.item-details {
386435
display: flex;
387436
flex-direction: column;
388-
gap: 0.15rem;
389-
font-size: 0.7rem;
437+
gap: 0.1rem;
438+
font-size: 0.65rem;
390439
color: var(--text-muted);
391-
margin-top: 0.05rem;
440+
margin-top: 0;
392441

393442
.item-description,
394443
.item-weight {
@@ -738,7 +787,7 @@
738787
justify-content: center;
739788
z-index: 2000;
740789
animation: fadeIn 0.2s ease-out;
741-
790+
backdrop-filter: blur(4px);
742791
@keyframes fadeIn {
743792
from {
744793
opacity: 0;
@@ -775,8 +824,8 @@
775824
align-items: center;
776825
background: linear-gradient(
777826
135deg,
778-
$primary 0%,
779-
color.adjust($primary, $lightness: -10%) 100%
827+
$neumorphic-surface 0%,
828+
color.adjust($neumorphic-surface, $lightness: -10%) 100%
780829
);
781830
border-radius: 16px 16px 0 0;
782831

@@ -818,13 +867,14 @@
818867

819868
.modal-body {
820869
padding: 2rem;
870+
background: $neumorphic-surface;
821871

822872
.sale-total {
823873
display: flex;
824874
justify-content: space-between;
825875
align-items: center;
826876
padding: 1.5rem;
827-
background: var(--bg-secondary);
877+
background: $white;
828878
border-radius: 12px;
829879
margin-bottom: 2rem;
830880

0 commit comments

Comments
 (0)