From 51eaaf50ef8e80c02feb161eb7f32a0d6084577b Mon Sep 17 00:00:00 2001 From: Anas Qureshi Date: Fri, 24 Jul 2026 17:14:32 +0530 Subject: [PATCH] new stepper changes --- package-lock.json | 90 +++ package.json | 4 +- src/app/features/dashboards/crm/crm.html | 5 + src/app/features/dashboards/crm/crm.ts | 6 +- .../stepper-four/stepper-four.component.html | 396 ++++++++++++ .../stepper-four/stepper-four.component.scss | 401 ++++++++++++ .../stepper-four.component.spec.ts | 28 + .../stepper-four/stepper-four.component.ts | 38 ++ .../stepper-three.component.html | 149 +++++ .../stepper-three.component.scss | 345 +++++++++++ .../stepper-three.component.spec.ts | 28 + .../stepper-three/stepper-three.component.ts | 26 + .../stepper-two/stepper-two.component.html | 575 ++++++++++++++++++ .../stepper-two/stepper-two.component.scss | 366 +++++++++++ .../stepper-two/stepper-two.component.spec.ts | 28 + .../stepper-two/stepper-two.component.ts | 25 + .../components/stepper/stepper.component.html | 293 +++++++++ .../components/stepper/stepper.component.scss | 357 +++++++++++ .../stepper/stepper.component.spec.ts | 28 + .../components/stepper/stepper.component.ts | 26 + 20 files changed, 3212 insertions(+), 2 deletions(-) create mode 100644 src/app/shared/components/stepper-four/stepper-four.component.html create mode 100644 src/app/shared/components/stepper-four/stepper-four.component.scss create mode 100644 src/app/shared/components/stepper-four/stepper-four.component.spec.ts create mode 100644 src/app/shared/components/stepper-four/stepper-four.component.ts create mode 100644 src/app/shared/components/stepper-three/stepper-three.component.html create mode 100644 src/app/shared/components/stepper-three/stepper-three.component.scss create mode 100644 src/app/shared/components/stepper-three/stepper-three.component.spec.ts create mode 100644 src/app/shared/components/stepper-three/stepper-three.component.ts create mode 100644 src/app/shared/components/stepper-two/stepper-two.component.html create mode 100644 src/app/shared/components/stepper-two/stepper-two.component.scss create mode 100644 src/app/shared/components/stepper-two/stepper-two.component.spec.ts create mode 100644 src/app/shared/components/stepper-two/stepper-two.component.ts create mode 100644 src/app/shared/components/stepper/stepper.component.html create mode 100644 src/app/shared/components/stepper/stepper.component.scss create mode 100644 src/app/shared/components/stepper/stepper.component.spec.ts create mode 100644 src/app/shared/components/stepper/stepper.component.ts diff --git a/package-lock.json b/package-lock.json index 741b5dc5..811a6b42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,8 @@ "ngx-echarts": "^21.0.0", "ngx-toastr": "^20.0.5", "preline": "^4.1.2", + "primeicons": "^8.0.0", + "primeng": "^21.1.9", "rxjs": "~7.8.0", "simplebar-angular": "^3.3.2", "sweetalert2": "^11.26.25", @@ -5092,6 +5094,66 @@ "license": "MIT", "optional": true }, + "node_modules/@primeuix/motion": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/@primeuix/motion/-/motion-0.0.10.tgz", + "integrity": "sha512-PsZwOPq79Scp7/ionshRcQ5xKVf9+zuLcyY5mf6onK8chHT5C9JGphmcIZ4CzcqxuGEpsm8AIbTGy+zS3RtzLA==", + "license": "MIT", + "dependencies": { + "@primeuix/utils": "^0.6.3" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/motion/node_modules/@primeuix/utils": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.6.4.tgz", + "integrity": "sha512-pZ5f+vj7wSzRhC7KoEQRU5fvYAe+RP9+m39CTscZ3UywCD1Y2o6Fe1rRgklMPSkzUcty2jzkA0zMYkiJBD1hgg==", + "license": "MIT", + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/styled": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@primeuix/styled/-/styled-0.7.4.tgz", + "integrity": "sha512-QSO/NpOQg8e9BONWRBx9y8VGMCMYz0J/uKfNJEya/RGEu7ARx0oYW0ugI1N3/KB1AAvyGxzKBzGImbwg0KUiOQ==", + "license": "MIT", + "dependencies": { + "@primeuix/utils": "^0.6.1" + }, + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/styled/node_modules/@primeuix/utils": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.6.4.tgz", + "integrity": "sha512-pZ5f+vj7wSzRhC7KoEQRU5fvYAe+RP9+m39CTscZ3UywCD1Y2o6Fe1rRgklMPSkzUcty2jzkA0zMYkiJBD1hgg==", + "license": "MIT", + "engines": { + "node": ">=12.11.0" + } + }, + "node_modules/@primeuix/styles": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@primeuix/styles/-/styles-2.0.3.tgz", + "integrity": "sha512-2ykAB6BaHzR/6TwF8ShpJTsZrid6cVIEBVlookSdvOdmlWuevGu5vWOScgIwqWwlZcvkFYAGR/SUV3OHCTBMdw==", + "license": "MIT", + "dependencies": { + "@primeuix/styled": "^0.7.4" + } + }, + "node_modules/@primeuix/utils": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@primeuix/utils/-/utils-0.7.2.tgz", + "integrity": "sha512-pmEbSfP0Phf9W9RweiM66zXnkn73ZeKyYINElbX3uZ2+stzzaba2svLAl3B1pHVcRw5t43O0VciaGe4ye2EXKw==", + "license": "MIT", + "engines": { + "node": ">=12.11.0" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -12388,6 +12450,34 @@ "node": ">= 0.8" } }, + "node_modules/primeicons": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/primeicons/-/primeicons-8.0.0.tgz", + "integrity": "sha512-eZGk+Mgb4fE+LkJi9LvllbnB4RVUF9kzmnLVnT3ZMY6stqKVh7TUJ0mFoMNIEgTnJSvhaGcJotDiSvtVvkHd7g==", + "license": "SEE LICENSE IN LICENSE.md" + }, + "node_modules/primeng": { + "version": "21.1.9", + "resolved": "https://registry.npmjs.org/primeng/-/primeng-21.1.9.tgz", + "integrity": "sha512-Z76PtF08X0PNSTCNMobao8Qm71vC56mtZSdUtX/gsn4+q4x0NbUUtkeK1pc33a+kxVm2zkmOwzUIEGmb9VdoIA==", + "license": "SEE LICENSE IN LICENSE.md", + "dependencies": { + "@primeuix/motion": "^0.0.10", + "@primeuix/styled": "^0.7.4", + "@primeuix/styles": "^2.0.3", + "@primeuix/utils": "^0.7.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/cdk": "^21.0.0", + "@angular/common": "^21.0.0", + "@angular/core": "^21.0.7", + "@angular/forms": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/router": "^21.0.0", + "rxjs": "^6.0.0 || ^7.8.1" + } + }, "node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", diff --git a/package.json b/package.json index 40272561..bc118502 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,8 @@ "ngx-echarts": "^21.0.0", "ngx-toastr": "^20.0.5", "preline": "^4.1.2", + "primeicons": "^8.0.0", + "primeng": "^21.1.9", "rxjs": "~7.8.0", "simplebar-angular": "^3.3.2", "sweetalert2": "^11.26.25", @@ -74,4 +76,4 @@ "typescript-eslint": "8.59.2", "vitest": "^4.0.8" } -} \ No newline at end of file +} diff --git a/src/app/features/dashboards/crm/crm.html b/src/app/features/dashboards/crm/crm.html index 55adc727..550a0045 100644 --- a/src/app/features/dashboards/crm/crm.html +++ b/src/app/features/dashboards/crm/crm.html @@ -1,3 +1,8 @@ + + + + +

Welcome back, diff --git a/src/app/features/dashboards/crm/crm.ts b/src/app/features/dashboards/crm/crm.ts index 12d5cc75..ed32f464 100644 --- a/src/app/features/dashboards/crm/crm.ts +++ b/src/app/features/dashboards/crm/crm.ts @@ -5,10 +5,14 @@ import { SpkApexcharts } from "../../../@spk/charts/charts/spk-apexcharts/spk-ap import { ApexOptions } from 'ng-apexcharts'; import { SpkReusableTables } from "../../../@spk/tables/spk-reusable-tables/spk-reusable-tables"; import { SpkChartjs } from "../../../@spk/charts/charts/spk-chartjs/spk-chartjs"; +import { StepperComponent } from "../../../shared/components/stepper/stepper.component"; +import { StepperTwoComponent } from "../../../shared/components/stepper-two/stepper-two.component"; +import { StepperThreeComponent } from "../../../shared/components/stepper-three/stepper-three.component"; +import { StepperFourComponent } from "../../../shared/components/stepper-four/stepper-four.component"; @Component({ selector: 'app-crm', standalone: true, - imports: [RouterModule, SpkApexcharts, SpkReusableTables, SpkChartjs], + imports: [RouterModule, SpkApexcharts, SpkReusableTables, SpkChartjs, StepperComponent, StepperTwoComponent, StepperThreeComponent, StepperFourComponent], templateUrl: './crm.html', styleUrl: './crm.scss' }) diff --git a/src/app/shared/components/stepper-four/stepper-four.component.html b/src/app/shared/components/stepper-four/stepper-four.component.html new file mode 100644 index 00000000..c8e25993 --- /dev/null +++ b/src/app/shared/components/stepper-four/stepper-four.component.html @@ -0,0 +1,396 @@ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ +
+
+ +
+ +
+
diff --git a/src/app/shared/components/stepper-four/stepper-four.component.scss b/src/app/shared/components/stepper-four/stepper-four.component.scss new file mode 100644 index 00000000..430bdcee --- /dev/null +++ b/src/app/shared/components/stepper-four/stepper-four.component.scss @@ -0,0 +1,401 @@ +$purple: #7c5cfa; +$purple-light: #e7dcff; +$line-grey: #e5e7eb; +$text-grey: #6b7280; +$text-dark: #1f2937; +$white: #ffffff; + +.custom-stepper-wrapper { + margin-top: 24px; + width: 100%; + background: #ffffff; + border-radius: 16px; + padding: 24px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + padding: 24px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + + ::ng-deep { + + .p-stepper { + background: transparent; + border: none; + box-shadow: none; + overflow: visible; + } + + .p-stepper-separator { + display: none !important; + } + + .p-step-list { + + display: flex; + justify-content: space-between; + align-items: center; + margin: 0 0 24px; + padding: 24px 32px; + background: $white; + border-radius: 16px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06); + overflow: visible; + } + + .p-step { + + flex: 1; + display: flex; + justify-content: center; + align-items: center; + padding: 0; + position: relative; + } + + .p-step:last-of-type { + flex: 1; + } + + .p-step-header { + + display: flex !important; + width: 100% !important; + padding: 0 !important; + background: transparent !important; + border: none !important; + } + } +} + +.step-button { + + display: flex; + flex-direction: row; + align-items: center; + gap: 12px; + width: 100%; + background: transparent; + border: none; + cursor: pointer; + color: $text-dark; + padding: 0; + + &:hover .step-icon:not(.active):not(.completed) { + border-color: $purple; + color: $purple; + } +} + +.step-icon { + + width: 48px; + height: 48px; + border-radius: 50%; + background: $white; + border: 2px solid $line-grey; + color: $text-grey; + font-size: 20px; + + display: flex; + justify-content: center; + align-items: center; + + transition: .3s; + position: relative; + z-index: 2; + flex-shrink: 0; + + &.completed { + + background: $purple; + border-color: $purple; + color: $white; + } + + &.active { + + background: $purple-light; + border-color: $purple; + color: $purple; + box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); + } +} + +.step-icon svg { + + width: 22px; + height: 22px; +} + +.step-label { + + font-size: 14px; + font-weight: 600; + color: $text-grey; + white-space: nowrap; + transition: color .3s; + + &.active, + &.completed { + color: $purple; + } +} + +.step-separator { + + flex: 1; + min-width: 24px; + margin-left: 16px; + margin-right: 16px; + border-top: 2px dotted #9ca3af; + height: 0; + transition: border-color .3s; + + &.completed { + border-color: $purple; + } +} + +.panel-card { + + background: $white; + border-radius: 16px; + padding: 32px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + min-height: 16rem; + margin: 0 auto; + + display: flex; + flex-direction: column; + gap: 16px; + + &.success { + + align-items: center; + justify-content: center; + text-align: center; + } + + p { + color: $text-grey; + text-align: center; + margin: 0; + } +} + +.panel-title { + + text-align: center; + font-size: 1.25rem; + font-weight: 600; + color: $text-dark; + margin-bottom: 8px; +} + +.success-icon { + + font-size: 64px; + color: $purple; + margin-top: 8px; +} + +.panel-footer { + + display: flex; + justify-content: flex-end; + align-items: center; + gap: 12px; + margin-top: 20px; +} + +.panel-form { + + background: $white; + border-radius: 16px; + padding: 32px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + margin: 0 auto; +} + +.custom-floating-field { + position: relative; + display: block; +} + +.custom-floating-input { + display: block; + width: 100%; + min-height: 2.5rem; + padding: 0.75rem 0.75rem 0.5rem; + border: 1px solid #d1d5db; + border-radius: 0.5rem; + background: #ffffff; + font-size: 0.8125rem; + line-height: 1.25; + color: #111827; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + outline: none; + box-sizing: border-box; +} + +.custom-floating-input:focus, +.custom-floating-input:not(:placeholder-shown), +.custom-floating-input:active { + border: 2px solid $purple; + outline: none; + box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); + animation: input-focus-ring 0.4s ease; +} + +@keyframes input-focus-ring { + 0% { box-shadow: 0 0 0 0 rgba(124, 92, 250, 0.3); } + 100% { box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); } +} + + +.custom-floating-input::placeholder { + color: transparent; +} + +.custom-floating-label { + position: absolute; + left: 0.75rem; + top: 50%; + transform: translateY(-50%); + transform-origin: left top; + background: #ffffff; + padding: 0 0.25rem; + color: #6b7280; + font-size: 0.8125rem; + line-height: 1.25; + pointer-events: none; + transition: top 0.2s ease, transform 0.2s ease, color 0.2s ease; + z-index: 1; + max-width: calc(100% - 1.5rem); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.custom-floating-input:focus~.custom-floating-label, +.custom-floating-input:not(:placeholder-shown)~.custom-floating-label { + top: 0; + transform: translateY(-50%) scale(0.9); + color: $purple; +} + +.custom-floating-input[type='number']::-webkit-inner-spin-button, +.custom-floating-input[type='number']::-webkit-outer-spin-button { + appearance: none; + margin: 0; +} + +.custom-floating-input[type='number'] { + -moz-appearance: textfield; +} + +// .panel-footer.between { + +// justify-content: space-between; +// } + +::ng-deep { + + .step-btn-next { + + background: linear-gradient(135deg, #7c5cfa, #a78bfa) !important; + color: $white !important; + border: none !important; + border-radius: 9999px !important; + padding: 0.55rem 1.4rem !important; + font-weight: 600 !important; + box-shadow: 0 4px 12px rgba(124, 92, 250, 0.35) !important; + transition: transform .2s, box-shadow .2s, filter .2s !important; + } + + .step-btn-next:hover { + + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(124, 92, 250, 0.45) !important; + filter: brightness(1.05); + } + + .step-btn-back { + + background: $white !important; + color: $text-grey !important; + border: 1px solid $line-grey !important; + border-radius: 9999px !important; + padding: 0.55rem 1.4rem !important; + font-weight: 600 !important; + transition: transform .2s, border-color .2s, color .2s, background .2s !important; + } + + .step-btn-back:hover { + + transform: translateY(-2px); + border-color: $purple !important; + color: $purple !important; + background: #f9fafb !important; + } +} + +@media (max-width: 768px) { + + .custom-stepper-wrapper { + max-width: 100%; + } + + ::ng-deep { + + .p-step-list { + padding: 16px; + overflow-x: auto; + } + + .p-step { + min-width: 120px; + } + } + + .step-icon { + + width: 40px; + height: 40px; + font-size: 16px; + } + + .step-icon svg { + width: 18px; + height: 18px; + } + + .step-label { + + font-size: 12px; + } + + .step-separator { + margin-left: 8px; + margin-right: 8px; + } + + .panel-card { + padding: 20px; + } + + .panel-form { + padding: 20px; + } + + .panel-title { + font-size: 1.1rem; + } +} + +::ng-deep .p-steplist { + padding: 10px; +} + +::ng-deep .p-steppanel-content { + margin-left: 0px !important; +} \ No newline at end of file diff --git a/src/app/shared/components/stepper-four/stepper-four.component.spec.ts b/src/app/shared/components/stepper-four/stepper-four.component.spec.ts new file mode 100644 index 00000000..80d1f0a8 --- /dev/null +++ b/src/app/shared/components/stepper-four/stepper-four.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { StepperFourComponent } from './stepper-four.component'; + +describe('StepperFourComponent', () => { + let component: StepperFourComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StepperFourComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StepperFourComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/stepper-four/stepper-four.component.ts b/src/app/shared/components/stepper-four/stepper-four.component.ts new file mode 100644 index 00000000..3ffa81dc --- /dev/null +++ b/src/app/shared/components/stepper-four/stepper-four.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { ButtonModule } from 'primeng/button'; +import { PasswordModule } from 'primeng/password'; +import { StepperModule } from 'primeng/stepper'; +import { ToggleButtonModule } from 'primeng/togglebutton'; +import { InputTextModule } from 'primeng/inputtext'; + +@Component({ + selector: 'app-stepper-four', + templateUrl: './stepper-four.component.html', + styleUrls: ['./stepper-four.component.scss'], + standalone: true, + imports: [CommonModule, ButtonModule, PasswordModule, StepperModule, ToggleButtonModule, InputTextModule, FormsModule] +}) +export class StepperFourComponent implements OnInit { + activeStep: number = 1; + name: string | undefined = undefined; + email: string | undefined = undefined; + password: string | undefined = undefined; + option1: boolean | undefined = false; + option2: boolean | undefined = false; + option3: boolean | undefined = false; + option4: boolean | undefined = false; + option5: boolean | undefined = false; + option6: boolean | undefined = false; + option7: boolean | undefined = false; + option8: boolean | undefined = false; + option9: boolean | undefined = false; + option10: boolean | undefined = false; + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/stepper-three/stepper-three.component.html b/src/app/shared/components/stepper-three/stepper-three.component.html new file mode 100644 index 00000000..3ccddfb5 --- /dev/null +++ b/src/app/shared/components/stepper-three/stepper-three.component.html @@ -0,0 +1,149 @@ +
+ + + + + + Header I + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+ +
+ + + + Header II + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+ +
+ + + + Header III + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+
+ +
+ +
+ +
diff --git a/src/app/shared/components/stepper-three/stepper-three.component.scss b/src/app/shared/components/stepper-three/stepper-three.component.scss new file mode 100644 index 00000000..e5da9bb4 --- /dev/null +++ b/src/app/shared/components/stepper-three/stepper-three.component.scss @@ -0,0 +1,345 @@ +$purple: #7c5cfa; +$purple-light: #e7dcff; +$line-grey: #e5e7eb; +$pending-text: #6b7280; +$title-color: #374151; +$active-text: #7c5cfa; +$white: #ffffff; +$card-bg: #ffffff; +$panel-bg: #f9fafb; +$panel-border: #dcdcdc; +$step-gap: 12px; +$step-gap-mobile: 10px; + +.card { + + background: $card-bg; + border-radius: 16px; + padding: 24px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + margin-top: 24px; +} + +::ng-deep { + + .p-stepper { + background: transparent !important; + border: none !important; + box-shadow: none !important; + overflow: visible !important; + } + + .p-stepper-separator { + display: none !important; + width: 0 !important; + height: 0 !important; + } + + .p-stepper .p-stepitem { + + position: relative !important; + z-index: 0 !important; + padding: 0 !important; + + &:not(:first-child) { + margin-top: $step-gap !important; + } + + &:not(:last-child)::after { + + content: ""; + position: absolute; + top: 40px; + left: 20px; + width: 2px; + bottom: -$step-gap; + background: $line-grey; + border-radius: 999px; + z-index: -1; + transition: background .35s ease; + } + + &.done:not(:last-child)::after { + + background: linear-gradient(180deg, $purple 0%, #a78bfa 100%); + } + } + + .p-stepper .p-step-header { + display: flex !important; + align-items: center !important; + gap: 12px !important; + background: transparent !important; + border: none !important; + padding: 0 !important; + width: 100% !important; + cursor: pointer !important; + } + + .p-stepper .p-step-number { + + width: 40px !important; + height: 40px !important; + border-radius: 50% !important; + background: $white !important; + border: 2px solid $line-grey !important; + color: $pending-text !important; + font-size: 14px !important; + font-weight: 700 !important; + display: flex !important; + justify-content: center !important; + align-items: center !important; + position: relative !important; + z-index: 2 !important; + transition: .3s !important; + } + + .p-stepper .p-step-active .p-step-number { + + background: $white !important; + border-color: $purple !important; + color: $purple !important; + box-shadow: 0 0 0 5px $purple-light !important; + transform: scale(1.08) !important; + } + + .p-stepper .p-stepitem.done .p-step-number { + + background: $purple !important; + border-color: $purple !important; + color: transparent !important; + } + + .p-stepper .p-stepitem.done .p-step-number::after { + + content: "✓"; + position: absolute; + inset: 0; + display: flex; + justify-content: center; + align-items: center; + color: $white; + font-size: 18px; + font-weight: 700; + } + + .p-stepper .p-step-title { + + font-size: 15px !important; + font-weight: 600 !important; + color: $title-color !important; + transition: color .3s !important; + } + + .p-stepper .p-step-active .p-step-title, + .p-stepper .p-stepitem.done .p-step-title { + + color: $purple !important; + } + + .p-stepper .p-steppanel-content-wrapper { + + display: block !important; + } + + .p-stepper .p-steppanel-content { + + padding: 16px 0 0 0 !important; + margin: 0 !important; + margin-left: 52px !important; + width: auto !important; + box-sizing: border-box !important; + } +} + +.panel-form { + + margin-bottom: 16px; + + form { + background: $panel-bg; + border: 2px dashed $panel-border; + border-radius: 12px; + padding: 24px; + } +} + +.custom-floating-field { + position: relative; + display: block; +} + +.custom-floating-input { + display: block; + width: 100%; + min-height: 2.5rem; + padding: 0.75rem 0.75rem 0.5rem; + border: 1px solid #d1d5db; + border-radius: 0.5rem; + background: #ffffff; + font-size: 0.8125rem; + line-height: 1.25; + color: #111827; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + outline: none; + box-sizing: border-box; +} + +.custom-floating-input:focus, +.custom-floating-input:not(:placeholder-shown), +.custom-floating-input:active { + border: 2px solid $purple; + outline: none; + box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); + animation: input-focus-ring 0.4s ease; +} + +@keyframes input-focus-ring { + 0% { box-shadow: 0 0 0 0 rgba(124, 92, 250, 0.3); } + 100% { box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); } +} + + +.custom-floating-input::placeholder { + color: transparent; +} + +.custom-floating-label { + position: absolute; + left: 0.75rem; + top: 50%; + transform: translateY(-50%); + transform-origin: left top; + background: #ffffff; + padding: 0 0.25rem; + color: #6b7280; + font-size: 0.8125rem; + line-height: 1.25; + pointer-events: none; + transition: top 0.2s ease, transform 0.2s ease, color 0.2s ease; + z-index: 1; + max-width: calc(100% - 1.5rem); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.custom-floating-input:focus~.custom-floating-label, +.custom-floating-input:not(:placeholder-shown)~.custom-floating-label { + top: 0; + transform: translateY(-50%) scale(0.9); + color: $purple; +} + +.custom-floating-input[type='number']::-webkit-inner-spin-button, +.custom-floating-input[type='number']::-webkit-outer-spin-button { + appearance: none; + margin: 0; +} + +.custom-floating-input[type='number'] { + -moz-appearance: textfield; +} + +.panel-footer { + + display: flex; + justify-content: flex-end; + align-items: center; + gap: 12px; + padding-bottom: 24px; +} + +// .panel-footer.between { + +// justify-content: space-between; +// } + +::ng-deep { + + .step-btn-next { + + background: linear-gradient(135deg, #7c5cfa, #a78bfa) !important; + color: $white !important; + border: none !important; + border-radius: 9999px !important; + padding: 0.55rem 1.4rem !important; + font-weight: 600 !important; + box-shadow: 0 4px 12px rgba(124, 92, 250, 0.35) !important; + transition: transform .2s, box-shadow .2s, filter .2s !important; + } + + .step-btn-next:hover { + + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(124, 92, 250, 0.45) !important; + filter: brightness(1.05); + } + + .step-btn-back { + + background: $white !important; + color: $pending-text !important; + border: 1px solid $line-grey !important; + border-radius: 9999px !important; + padding: 0.55rem 1.4rem !important; + font-weight: 600 !important; + transition: transform .2s, border-color .2s, color .2s, background .2s !important; + } + + .step-btn-back:hover { + + transform: translateY(-2px); + border-color: $purple !important; + color: $purple !important; + background: #f9fafb !important; + } +} + +@media (max-width: 768px) { + + .card { + padding: 16px; + } + + ::ng-deep { + + .p-stepper .p-stepitem:not(:first-child) { + margin-top: $step-gap-mobile !important; + } + + .p-stepper .p-stepitem:not(:last-child)::after { + top: 34px; + left: 17px; + bottom: -$step-gap-mobile; + } + + .p-stepper .p-step-number { + width: 34px !important; + height: 34px !important; + font-size: 12px !important; + } + + .p-stepper .p-step-active .p-step-number { + box-shadow: 0 0 0 4px $purple-light !important; + } + + .p-stepper .p-step-title { + font-size: 13px !important; + } + + .p-stepper .p-steppanel-content { + margin-left: 44px !important; + width: auto !important; + padding-top: 12px !important; + } + } + + .panel-form form { + padding: 16px; + } + + .panel-footer { + margin-left: 0; + } +} \ No newline at end of file diff --git a/src/app/shared/components/stepper-three/stepper-three.component.spec.ts b/src/app/shared/components/stepper-three/stepper-three.component.spec.ts new file mode 100644 index 00000000..a2ed0431 --- /dev/null +++ b/src/app/shared/components/stepper-three/stepper-three.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { StepperThreeComponent } from './stepper-three.component'; + +describe('StepperThreeComponent', () => { + let component: StepperThreeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StepperThreeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StepperThreeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/stepper-three/stepper-three.component.ts b/src/app/shared/components/stepper-three/stepper-three.component.ts new file mode 100644 index 00000000..146561a4 --- /dev/null +++ b/src/app/shared/components/stepper-three/stepper-three.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ButtonModule } from 'primeng/button'; +import { StepperModule } from 'primeng/stepper'; + +@Component({ + selector: 'app-stepper-three', + templateUrl: './stepper-three.component.html', + styleUrls: ['./stepper-three.component.scss'], + standalone: true, + imports: [CommonModule, ButtonModule, StepperModule] +}) +export class StepperThreeComponent implements OnInit { + + activeStep = 1; + + changeStep(step: number) { + this.activeStep = step; + } + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/stepper-two/stepper-two.component.html b/src/app/shared/components/stepper-two/stepper-two.component.html new file mode 100644 index 00000000..4e1aac16 --- /dev/null +++ b/src/app/shared/components/stepper-two/stepper-two.component.html @@ -0,0 +1,575 @@ +
+ + + + + + + + +
+ +
+ @if (activeStep > 1) { + + + + } @else { + 1 + } +
+ +
+ +
Step 1
+
Plan
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 2) { + + + + } @else { + 2 + } +
+ +
+ +
Step 2
+
Design
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 3) { + + + + } @else { + 3 + } +
+ +
+ +
Step 3
+
Build
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 4) { + + + + } @else { + 4 + } +
+ +
+ +
Step 4
+
Test
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 5) { + + + + } @else { + 5 + } +
+ +
+ +
Step 5
+
Deploy
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 6) { + + + + } @else { + 6 + } +
+ +
+ +
Step 6
+
Launch
+ +
+ +
+ +
+ +
+ +
+ + + + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ +
+ +
+ +
diff --git a/src/app/shared/components/stepper-two/stepper-two.component.scss b/src/app/shared/components/stepper-two/stepper-two.component.scss new file mode 100644 index 00000000..9a01faae --- /dev/null +++ b/src/app/shared/components/stepper-two/stepper-two.component.scss @@ -0,0 +1,366 @@ +$purple: #7c5cfa; +$purple-light: #e7dcff; +$line-grey: #e5e7eb; +$dot-grey: #d1d5db; +$title-color: #374151; +$subtitle-color: #6b7280; + +.custom-stepper-wrapper { + background: #f9fafb; + padding: 20px; + margin-top: 30px !important; + width: 100%; + --completed-width: 0%; + + ::ng-deep { + + .p-stepper { + background: transparent; + border: none; + box-shadow: none; + overflow: visible; + } + + .p-stepper-separator { + display: none !important; + } + + .p-step-list { + + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 24px; + overflow: visible; + } + + .p-step { + + flex: 1; + position: relative; + display: flex; + justify-content: center; + align-items: flex-start; + padding: 0; + z-index: 1; + } + + .p-step:last-of-type { + flex: 1; + } + + .p-step:not(:last-child)::after { + + content: ""; + position: absolute; + top: 20px; + left: calc(50% + 20px); + width: calc(100% - 40px); + height: 4px; + background: $line-grey; + border-radius: 999px; + z-index: 0; + transition: background .35s ease; + } + + .p-step.done:not(:last-child)::after { + + background: linear-gradient(90deg, $purple 0%, #a78bfa 100%); + } + } +} + +.custom-step { + + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.step-circle { + + width: 40px; + height: 40px; + border-radius: 50%; + background: white; + border: 2px solid $line-grey; + + display: flex; + justify-content: center; + align-items: center; + + transition: .3s; + position: relative; + z-index: 2; + cursor: pointer; + + .step-number { + + font-size: 14px; + font-weight: 700; + color: $subtitle-color; + line-height: 1; + } + + &.completed { + + background: $purple; + border-color: $purple; + transform: scale(1.05); + + .step-number { + display: none; + } + + .check-icon { + + color: white; + width: 18px; + height: 18px; + } + } + + &.active { + + background: white; + border-color: $purple; + box-shadow: 0 0 0 5px $purple-light; + transform: scale(1.08); + + .step-number { + color: $purple; + } + } +} + +.check-icon { + + width: 18px; + height: 18px; + color: white; +} + +.step-text { + + text-align: center; + + .step-title { + + font-size: 14px; + font-weight: 600; + color: $title-color; + } + + .step-subtitle { + + margin-top: 2px; + font-size: 12px; + color: $subtitle-color; + } + + &.active { + + .step-title, + .step-subtitle { + + color: $purple; + } + } + + &.completed { + + .step-title, + .step-subtitle { + + color: $purple; + } + } +} + +.panel-box { + + border: 2px dashed #dcdcdc; + border-radius: 12px; + height: 220px; + + display: flex; + justify-content: center; + align-items: center; + + margin-top: 40px; +} + +.panel-form { + margin-top: 40px; +} + +.custom-floating-field { + position: relative; + display: block; +} + +.custom-floating-input { + display: block; + width: 100%; + min-height: 2.5rem; + padding: 0.75rem 0.75rem 0.5rem; + border: 1px solid #d1d5db; + border-radius: 0.5rem; + background: #ffffff; + font-size: 0.8125rem; + line-height: 1.25; + color: #111827; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + outline: none; + box-sizing: border-box; +} + +.custom-floating-input:focus, +.custom-floating-input:not(:placeholder-shown), +.custom-floating-input:active { + border: 2px solid $purple; + outline: none; + box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); + animation: input-focus-ring 0.4s ease; +} + +@keyframes input-focus-ring { + 0% { box-shadow: 0 0 0 0 rgba(124, 92, 250, 0.3); } + 100% { box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); } +} + + +.custom-floating-input::placeholder { + color: transparent; +} + +.custom-floating-label { + position: absolute; + left: 0.75rem; + top: 50%; + transform: translateY(-50%); + transform-origin: left top; + background: #ffffff; + padding: 0 0.25rem; + color: #6b7280; + font-size: 0.8125rem; + line-height: 1.25; + pointer-events: none; + transition: top 0.2s ease, transform 0.2s ease, color 0.2s ease; + z-index: 1; + max-width: calc(100% - 1.5rem); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.custom-floating-input:focus~.custom-floating-label, +.custom-floating-input:not(:placeholder-shown)~.custom-floating-label { + top: 0; + transform: translateY(-50%) scale(0.9); + color: $purple; +} + +.custom-floating-input[type='number']::-webkit-inner-spin-button, +.custom-floating-input[type='number']::-webkit-outer-spin-button { + appearance: none; + margin: 0; +} + +.custom-floating-input[type='number'] { + -moz-appearance: textfield; +} + +.panel-footer { + + display: flex; + justify-content: flex-end; + align-items: center; + gap: 12px; + margin-top: 20px; +} + +// .panel-footer.between { + +// justify-content: space-between; +// } + +::ng-deep { + + .step-btn-next { + + background: linear-gradient(135deg, #7c5cfa, #a78bfa) !important; + color: #fff !important; + border: none !important; + border-radius: 9999px !important; + padding: 0.5rem 1.25rem !important; + font-weight: 600 !important; + box-shadow: 0 4px 12px rgba(124, 92, 250, 0.35) !important; + transition: transform .2s, box-shadow .2s, filter .2s !important; + } + + .step-btn-next:hover { + + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(124, 92, 250, 0.45) !important; + filter: brightness(1.05); + } + + .step-btn-back { + + background: #fff !important; + color: #6b7280 !important; + border: 1px solid #e5e7eb !important; + border-radius: 9999px !important; + padding: 0.5rem 1.25rem !important; + font-weight: 600 !important; + transition: transform .2s, border-color .2s, background .2s, color .2s !important; + } + + .step-btn-back:hover { + + transform: translateY(-2px); + background: #f9fafb !important; + border-color: #7c5cfa !important; + color: #7c5cfa !important; + } +} + +@media (max-width: 768px) { + + .step-text .step-title { + + font-size: 12px; + } + + .step-text .step-subtitle { + + font-size: 11px; + } + + .step-circle { + + width: 34px; + height: 34px; + + .step-number { + font-size: 12px; + } + } + + .step-circle.active { + + box-shadow: 0 0 0 4px $purple-light; + } + + .p-step-list::before, + .p-step-list::after { + + top: 17px; + } +} + +::ng-deep .p-steplist { + padding-top: 15px !important; +} \ No newline at end of file diff --git a/src/app/shared/components/stepper-two/stepper-two.component.spec.ts b/src/app/shared/components/stepper-two/stepper-two.component.spec.ts new file mode 100644 index 00000000..235e9aa3 --- /dev/null +++ b/src/app/shared/components/stepper-two/stepper-two.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { StepperTwoComponent } from './stepper-two.component'; + +describe('StepperTwoComponent', () => { + let component: StepperTwoComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StepperTwoComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StepperTwoComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/stepper-two/stepper-two.component.ts b/src/app/shared/components/stepper-two/stepper-two.component.ts new file mode 100644 index 00000000..d9db487d --- /dev/null +++ b/src/app/shared/components/stepper-two/stepper-two.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ButtonModule } from 'primeng/button'; +import { StepperModule } from 'primeng/stepper'; +@Component({ + selector: 'app-stepper-two', + templateUrl: './stepper-two.component.html', + styleUrls: ['./stepper-two.component.scss'], + standalone: true, + imports: [CommonModule, ButtonModule, StepperModule] +}) +export class StepperTwoComponent implements OnInit { + + activeStep = 1; + + changeStep(step: number) { + this.activeStep = step; + } + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/stepper/stepper.component.html b/src/app/shared/components/stepper/stepper.component.html new file mode 100644 index 00000000..8e39a118 --- /dev/null +++ b/src/app/shared/components/stepper/stepper.component.html @@ -0,0 +1,293 @@ +
+ + + + + + + + +
+ +
+ @if (activeStep > 1) { + + + + } @else if (activeStep === 1) { + + } @else { + + } +
+ +
+ +
Step 1
+
Plan
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 2) { + + + + } @else if (activeStep === 2) { + + } @else { + + } +
+ +
+ +
Step 2
+
Payment
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ @if (activeStep > 3) { + + + + } @else if (activeStep === 3) { + + } @else { + + } +
+ +
+ +
Step 3
+
Confirm
+ +
+ +
+ +
+ +
+ +
+ + + + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ + + + + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + + +
+ +
+ +
+ +
+ +
diff --git a/src/app/shared/components/stepper/stepper.component.scss b/src/app/shared/components/stepper/stepper.component.scss new file mode 100644 index 00000000..6499241c --- /dev/null +++ b/src/app/shared/components/stepper/stepper.component.scss @@ -0,0 +1,357 @@ +$purple: #7c5cfa; +$purple-light: #e7dcff; +$line-grey: #e5e7eb; +$dot-grey: #d1d5db; +$title-color: #374151; +$subtitle-color: #6b7280; + +.custom-stepper-wrapper { + background: #ffffff; + border-radius: 16px; + padding: 24px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.06); + padding: 20px; + margin-top: 30px !important; + width: 100%; + --completed-width: 0%; + + ::ng-deep { + + .p-stepper { + background: transparent; + border: none; + box-shadow: none; + overflow: visible; + } + + .p-stepper-separator { + display: none !important; + } + + .p-step-list { + + display: flex; + justify-content: space-between; + align-items: flex-start; + margin-bottom: 16px; + position: relative; + overflow: visible; + } + + .p-step-list::before { + + content: ""; + position: absolute; + top: 16px; + left: 0; + width: 100%; + height: 2px; + background: $line-grey; + z-index: 0; + } + + .p-step-list::after { + + content: ""; + position: absolute; + top: 16px; + left: 0; + width: var(--completed-width); + height: 2px; + background: $purple; + z-index: 0; + transition: width .3s; + } + + .p-step { + + flex: 1; + position: relative; + display: flex; + justify-content: center; + align-items: flex-start; + padding: 0; + z-index: 1; + } + + .p-step:last-of-type { + flex: 1; + } + } +} + +.custom-step { + + display: flex; + flex-direction: column; + align-items: center; + gap: 6px; +} + +.step-circle { + + width: 32px; + height: 32px; + border-radius: 50%; + background: white; + border: 2px solid $line-grey; + + display: flex; + justify-content: center; + align-items: center; + + transition: .3s; + position: relative; + z-index: 2; + cursor: pointer; + + &.completed { + + background: $purple; + border-color: $purple; + + .check-icon { + + color: white; + width: 16px; + height: 16px; + } + } + + &.active { + + background: $purple; + border-color: $purple; + box-shadow: 0 0 0 4px $purple-light; + + .dot { + + width: 8px; + height: 8px; + background: white; + border-radius: 50%; + } + } +} + +.grey-dot { + + width: 8px; + height: 8px; + background: $dot-grey; + border-radius: 50%; +} + +.check-icon { + + width: 16px; + height: 16px; + color: white; +} + +.step-text { + + text-align: center; + + .step-title { + + font-size: 14px; + font-weight: 600; + color: $title-color; + } + + .step-subtitle { + + margin-top: 2px; + font-size: 12px; + color: $subtitle-color; + } + + &.active { + + .step-title, + .step-subtitle { + + color: $purple; + } + } +} + +.panel-box { + + border: 2px dashed #dcdcdc; + border-radius: 12px; + height: 220px; + + display: flex; + justify-content: center; + align-items: center; + + margin-top: 40px; +} + +.panel-footer { + + display: flex; + justify-content: flex-end; + align-items: center; + gap: 12px; + margin-top: 20px; +} + +.panel-form { + margin-top: 40px; +} + +.custom-floating-field { + position: relative; + display: block; +} + +.custom-floating-input { + display: block; + width: 100%; + min-height: 2.5rem; + padding: 0.75rem 0.75rem 0.5rem; + border: 1px solid #d1d5db; + border-radius: 0.5rem; + background: #ffffff; + font-size: 0.8125rem; + line-height: 1.25; + color: #111827; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + outline: none; + box-sizing: border-box; +} + +.custom-floating-input:focus, +.custom-floating-input:not(:placeholder-shown), +.custom-floating-input:active { + border: 2px solid $purple; + outline: none; + box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); + animation: input-focus-ring 0.4s ease; +} + +@keyframes input-focus-ring { + 0% { box-shadow: 0 0 0 0 rgba(124, 92, 250, 0.3); } + 100% { box-shadow: 0 0 0 4px rgba(124, 92, 250, 0.15); } +} + + +.custom-floating-input::placeholder { + color: transparent; +} + +.custom-floating-label { + position: absolute; + left: 0.75rem; + top: 50%; + transform: translateY(-50%); + transform-origin: left top; + background: #ffffff; + padding: 0 0.25rem; + color: #6b7280; + font-size: 0.8125rem; + line-height: 1.25; + pointer-events: none; + transition: top 0.2s ease, transform 0.2s ease, color 0.2s ease; + z-index: 1; + max-width: calc(100% - 1.5rem); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.custom-floating-input:focus~.custom-floating-label, +.custom-floating-input:not(:placeholder-shown)~.custom-floating-label { + top: 0; + transform: translateY(-50%) scale(0.9); + color: $purple; +} + +.custom-floating-input[type='number']::-webkit-inner-spin-button, +.custom-floating-input[type='number']::-webkit-outer-spin-button { + appearance: none; + margin: 0; +} + +.custom-floating-input[type='number'] { + -moz-appearance: textfield; +} + +// .panel-footer.between { + +// justify-content: space-between; +// } + +::ng-deep { + + .step-btn-next { + + background: linear-gradient(135deg, #7c5cfa, #a78bfa) !important; + color: #fff !important; + border: none !important; + border-radius: 9999px !important; + padding: 0.5rem 1.25rem !important; + font-weight: 600 !important; + box-shadow: 0 4px 12px rgba(124, 92, 250, 0.35) !important; + transition: transform .2s, box-shadow .2s, filter .2s !important; + } + + .step-btn-next:hover { + + transform: translateY(-2px); + box-shadow: 0 6px 16px rgba(124, 92, 250, 0.45) !important; + filter: brightness(1.05); + } + + .step-btn-back { + + background: #fff !important; + color: #6b7280 !important; + border: 1px solid #e5e7eb !important; + border-radius: 9999px !important; + padding: 0.5rem 1.25rem !important; + font-weight: 600 !important; + transition: transform .2s, border-color .2s, background .2s, color .2s !important; + } + + .step-btn-back:hover { + + transform: translateY(-2px); + background: #f9fafb !important; + border-color: #7c5cfa !important; + color: #7c5cfa !important; + } +} + +@media (max-width: 768px) { + + .step-text .step-title { + + font-size: 12px; + } + + .step-text .step-subtitle { + + font-size: 11px; + } + + .step-circle { + + width: 28px; + height: 28px; + } + + .step-circle.active { + + box-shadow: 0 0 0 3px $purple-light; + } + + .p-step-list::before, + .p-step-list::after { + + top: 14px; + } +} \ No newline at end of file diff --git a/src/app/shared/components/stepper/stepper.component.spec.ts b/src/app/shared/components/stepper/stepper.component.spec.ts new file mode 100644 index 00000000..b6d9583d --- /dev/null +++ b/src/app/shared/components/stepper/stepper.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { StepperComponent } from './stepper.component'; + +describe('StepperComponent', () => { + let component: StepperComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StepperComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StepperComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/stepper/stepper.component.ts b/src/app/shared/components/stepper/stepper.component.ts new file mode 100644 index 00000000..9bb1a995 --- /dev/null +++ b/src/app/shared/components/stepper/stepper.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ButtonModule } from 'primeng/button'; +import { StepperModule } from 'primeng/stepper'; + +@Component({ + selector: 'app-stepper', + templateUrl: './stepper.component.html', + styleUrls: ['./stepper.component.scss'] , + standalone: true, + imports: [CommonModule, ButtonModule, StepperModule] +}) +export class StepperComponent implements OnInit { + + activeStep = 1; + + changeStep(step: number) { + this.activeStep = step; + } + + constructor() { } + + ngOnInit() { + } + +}