From f5691d9532ac889263cb4ff4e7afc0a3b19ba0db Mon Sep 17 00:00:00 2001 From: thekevinm Date: Wed, 13 Aug 2025 00:01:09 +0000 Subject: [PATCH] Refined the congrats popup and quick stats --- .../df-dashboard-card.component.html | 6 +- .../df-dashboard-card.component.scss | 267 ++++++++--------- .../df-dashboard-card.component.ts | 1 + .../df-dashboard/df-dashboard.component.html | 3 + .../df-service-details.component.html | 14 +- .../df-service-details.component.scss | 14 +- .../df-service-details.component.ts | 2 +- .../df-celebration-dialog.component.html | 112 ++++--- .../df-celebration-dialog.component.scss | 282 +++++++++++++----- .../df-celebration-dialog.component.ts | 38 ++- .../df-security-config.component.ts | 3 +- src/assets/i18n/services/en.json | 12 +- src/styles.scss | 2 +- 13 files changed, 464 insertions(+), 292 deletions(-) diff --git a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.html b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.html index 8b00107b..3ca831db 100644 --- a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.html +++ b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.html @@ -2,7 +2,6 @@ class="dashboard-card" [class]="'card-' + color" [class.zero-value]="isZero" - [class.shake-animation]="isZero" [class.clickable]="clickable" (click)="onClick()"> @@ -20,8 +19,9 @@

{{ title }}

-
{{ value }}
-

{{ subtitle }}

+
{{ value }}
+
{{ zeroStateText }}
+

{{ subtitle }}

diff --git a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.scss b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.scss index 7c52d769..952f70d0 100644 --- a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.scss +++ b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.scss @@ -12,7 +12,7 @@ &.clickable { cursor: pointer; - + &:hover { transform: translateY(-4px); box-shadow: 0 6px 25px rgba(0, 0, 0, 0.15); @@ -38,6 +38,9 @@ display: flex; align-items: center; justify-content: center; + position: relative; + z-index: 1; + transition: transform 0.3s ease; fa-icon { font-size: 24px; @@ -100,6 +103,18 @@ font-weight: 600; color: #333; line-height: 1.2; + + &.zero-state-cta { + font-size: 20px; + font-weight: 600; + line-height: 1.3; + background: linear-gradient(135deg, #7f11e0, #9333ea); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + padding: 8px 0; + transition: all 0.3s ease; + } } .card-subtitle { @@ -120,160 +135,114 @@ } } -// Prompt styling +// Prompt styling - professional and clean ::ng-deep [prompt] { - font-size: 14px; - color: #d32f2f; - font-weight: 600; + font-size: 13px; + color: #666; + font-weight: 400; display: flex; align-items: center; - gap: 6px; - animation: urgent-pulse 1.5s infinite; - text-shadow: 0 0 8px rgba(211, 47, 47, 0.3); - letter-spacing: 0.5px; + gap: 8px; + margin-top: 12px; + padding: 8px 12px; + background: rgba(127, 17, 224, 0.04); + border-radius: 6px; + transition: all 0.2s ease; span { position: relative; - - &::after { - content: ''; - position: absolute; - bottom: -2px; - left: 0; - right: 0; - height: 2px; - background: linear-gradient(90deg, transparent, #d32f2f, transparent); - animation: underline-slide 2s infinite; - } - } -} - -@keyframes urgent-pulse { - 0%, - 100% { - opacity: 0.9; - transform: scale(1); - } - 50% { - opacity: 1; - transform: scale(1.02); - } -} - -@keyframes underline-slide { - 0% { - transform: translateX(-100%); - } - 100% { - transform: translateX(100%); + flex: 1; } } -@keyframes pulse { - 0% { - opacity: 0.8; - } - 50% { - opacity: 1; - } - 100% { - opacity: 0.8; - } -} - -// Zero value styling +// Zero value styling - professional and inviting .dashboard-card.zero-value { - background: linear-gradient(135deg, #fff5f5 0%, #ffe0e0 100%); - border: 2px solid #ff6b6b; + background: #ffffff; + border: 1.5px solid rgba(147, 51, 234, 0.3); position: relative; overflow: hidden; - box-shadow: 0 0 20px rgba(255, 107, 107, 0.2); - animation: glow-pulse 2.5s infinite; + box-shadow: 0 2px 12px rgba(147, 51, 234, 0.08); + cursor: pointer !important; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); &::before { content: ''; position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - background: linear-gradient( - 90deg, - transparent, - rgba(255, 107, 107, 0.3), - transparent - ); - animation: shimmer 3s infinite; - } - - .card-value { - color: #d32f2f !important; - font-weight: 700 !important; - text-shadow: 0 0 3px rgba(211, 47, 47, 0.2); + top: 0; + left: 0; + right: 0; + height: 2px; + background: linear-gradient(90deg, #7f11e0, #9333ea); + opacity: 1; } .icon-container { - animation: attention-pulse 2s infinite; - box-shadow: 0 0 15px rgba(255, 107, 107, 0.3); + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08); + + // Keep original colors for each icon type + &.icon-primary { + background: linear-gradient(135deg, #7f11e0 0%, #5c239a 100%); + } + + &.icon-success { + background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%); + } + + &.icon-info { + background: linear-gradient(135deg, #2196f3 0%, #1976d2 100%); + } } - &:hover { - transform: translateY(-2px) scale(1.02); - box-shadow: 0 4px 30px rgba(255, 107, 107, 0.3); + .card-value.zero-state-cta { + position: relative; + + &::after { + content: '→'; + position: absolute; + right: -25px; + top: 50%; + transform: translateY(-50%); + font-size: 20px; + color: #9333ea; + opacity: 0; + transition: all 0.3s ease; + } } -} -@keyframes glow-pulse { - 0%, - 100% { - box-shadow: 0 0 20px rgba(255, 107, 107, 0.2); - } - 50% { - box-shadow: 0 0 30px rgba(255, 107, 107, 0.4); + ::ng-deep [prompt] { + background: rgba(127, 17, 224, 0.06); + color: #7f11e0; + font-weight: 500; } -} -// Shake animation for zero value cards -.dashboard-card.shake-animation { - animation: subtle-shake 4s infinite; -} + &:hover { + transform: translateY(-6px); + box-shadow: 0 12px 28px rgba(147, 51, 234, 0.15); + border-color: rgba(127, 17, 224, 0.5); + background: linear-gradient(180deg, #ffffff 0%, #faf8ff 100%); -@keyframes subtle-shake { - 0%, - 90%, - 100% { - transform: translateX(0); - } - 92% { - transform: translateX(-2px) rotate(-0.5deg); - } - 94% { - transform: translateX(2px) rotate(0.5deg); - } - 96% { - transform: translateX(-1px) rotate(-0.3deg); - } - 98% { - transform: translateX(1px) rotate(0.3deg); - } -} + .icon-container { + transform: scale(1.08); + } -@keyframes shimmer { - 0% { - transform: translateX(-100%); - } - 100% { - transform: translateX(200%); - } -} + .card-value.zero-state-cta { + transform: translateX(-5px); + + &::after { + opacity: 1; + right: -30px; + } + } -@keyframes attention-pulse { - 0%, - 100% { - transform: scale(1); + ::ng-deep [prompt] { + background: rgba(127, 17, 224, 0.08); + transform: translateY(-1px); + } } - 50% { - transform: scale(1.1); + + &:active { + transform: translateY(-3px); + box-shadow: 0 6px 16px rgba(147, 51, 234, 0.12); } } @@ -289,6 +258,13 @@ .card-value { color: #fff; + + &.zero-state-cta { + background: linear-gradient(135deg, #bb86fc, #9333ea); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + } } .card-subtitle { @@ -305,30 +281,35 @@ } &.zero-value { - background: linear-gradient(135deg, #4a1a1a 0%, #3d1515 100%); - border: 2px solid #ff6b6b; + background: #2e2e2e; + border: 1.5px solid rgba(147, 51, 234, 0.4); + box-shadow: 0 2px 12px rgba(147, 51, 234, 0.12); &::before { - background: linear-gradient( - 90deg, - transparent, - rgba(255, 107, 107, 0.2), - transparent - ); + background: linear-gradient(90deg, #bb86fc, #9333ea); } - .card-value { - color: #ff8a80 !important; + .card-value.zero-state-cta { + &::after { + color: #bb86fc; + } + } + + &:hover { + background: linear-gradient(180deg, #2e2e2e 0%, #352840 100%); + border-color: rgba(187, 134, 252, 0.6); + box-shadow: 0 12px 28px rgba(187, 134, 252, 0.2); + } + + ::ng-deep [prompt] { + background: rgba(187, 134, 252, 0.08); + color: #bb86fc; } } } ::ng-deep [prompt] { - color: #ff8a80; - text-shadow: 0 0 10px rgba(255, 138, 128, 0.5); - - span::after { - background: linear-gradient(90deg, transparent, #ff8a80, transparent); - } + color: #aaa; + background: rgba(255, 255, 255, 0.04); } -} +} \ No newline at end of file diff --git a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.ts b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.ts index d8ba3fed..33ee8194 100644 --- a/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.ts +++ b/src/app/adf-home/df-dashboard/df-dashboard-card/df-dashboard-card.component.ts @@ -22,6 +22,7 @@ export class DfDashboardCardComponent { @Input() footerText?: string; @Input() showPrompt?: boolean = false; @Input() isZero?: boolean = false; + @Input() zeroStateText?: string = 'Click to get started!'; @Input() color: 'primary' | 'accent' | 'success' | 'info' | 'warn' = 'primary'; @Input() clickable?: boolean = false; diff --git a/src/app/adf-home/df-dashboard/df-dashboard.component.html b/src/app/adf-home/df-dashboard/df-dashboard.component.html index 06e06eda..c9b9eba7 100644 --- a/src/app/adf-home/df-dashboard/df-dashboard.component.html +++ b/src/app/adf-home/df-dashboard/df-dashboard.component.html @@ -22,6 +22,7 @@

{{ 'home.dashboard.title' | transloco }}

[subtitle]="'home.dashboard.services.total' | transloco" [showPrompt]="stats.services.total === 0" [isZero]="stats.services.total === 0" + [zeroStateText]="'Create your first API'" [clickable]="stats.services.total === 0" (cardClick)="onServicesCardClick()" color="primary"> @@ -38,6 +39,7 @@

{{ 'home.dashboard.title' | transloco }}

[subtitle]="'home.dashboard.apiKeys.total' | transloco" [showPrompt]="stats.apiKeys.total === 0" [isZero]="stats.apiKeys.total === 0" + [zeroStateText]="'Generate your API key'" [clickable]="stats.apiKeys.total === 0" (cardClick)="onApiKeysCardClick()" color="success"> @@ -54,6 +56,7 @@

{{ 'home.dashboard.title' | transloco }}

[subtitle]="'home.dashboard.roles.total' | transloco" [showPrompt]="stats.roles.total === 0" [isZero]="stats.roles.total === 0" + [zeroStateText]="'Set up your first role'" [clickable]="stats.roles.total === 0" (cardClick)="onRolesCardClick()" color="info"> diff --git a/src/app/adf-services/df-service-details/df-service-details.component.html b/src/app/adf-services/df-service-details/df-service-details.component.html index 00ab0d0f..e9a28bbc 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.html +++ b/src/app/adf-services/df-service-details/df-service-details.component.html @@ -367,13 +367,15 @@

-
+

{{ 'services.firstTimeGuidance' | transloco }}

- +
- + - diff --git a/src/app/adf-services/df-service-details/df-service-details.component.scss b/src/app/adf-services/df-service-details/df-service-details.component.scss index ea1e6c52..d9d38dcd 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.scss +++ b/src/app/adf-services/df-service-details/df-service-details.component.scss @@ -613,13 +613,13 @@ mat-icon { background: linear-gradient(135deg, #f3e7ff 0%, #e8d5ff 100%); border-radius: 8px; border-left: 4px solid mat.get-color-from-palette($df-purple-palette, 500); - + .guidance-icon { color: mat.get-color-from-palette($df-purple-palette, 600); font-size: 20px; flex-shrink: 0; } - + .guidance-text { margin: 0; color: #4a4a4a; @@ -631,13 +631,17 @@ mat-icon { .dark-theme { .first-time-guidance { - background: linear-gradient(135deg, rgba(124, 77, 255, 0.15) 0%, rgba(124, 77, 255, 0.1) 100%); + background: linear-gradient( + 135deg, + rgba(124, 77, 255, 0.15) 0%, + rgba(124, 77, 255, 0.1) 100% + ); border-left-color: mat.get-color-from-palette($df-purple-palette, 300); - + .guidance-icon { color: mat.get-color-from-palette($df-purple-palette, 300); } - + .guidance-text { color: rgba(255, 255, 255, 0.87); } diff --git a/src/app/adf-services/df-service-details/df-service-details.component.ts b/src/app/adf-services/df-service-details/df-service-details.component.ts index a08f6a6d..a10b3357 100644 --- a/src/app/adf-services/df-service-details/df-service-details.component.ts +++ b/src/app/adf-services/df-service-details/df-service-details.component.ts @@ -217,7 +217,7 @@ export class DfServiceDetailsComponent implements OnInit { this.isFirstTimeUser = stats.services.total === 0; }); } - + this.http .get>('assets/img/databaseImages.json') .subscribe(images => { diff --git a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.html b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.html index fcd612b5..e03bdb43 100644 --- a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.html +++ b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.html @@ -1,8 +1,14 @@
-
-
+
+
@@ -17,27 +23,31 @@

{{ 'services.celebration.title' | transloco }}

- {{ 'services.celebration.subtitle' | transloco: { name: data.serviceName } }} + {{ + 'services.celebration.subtitle' + | transloco: { name: data.serviceName } + }}

-

{{ 'services.celebration.whatHappened' | transloco }}

- +

+ {{ 'services.celebration.whatHappened' | transloco }} +

+
-
-
- +
- +

{{ step.title | transloco }}

{{ step.description | transloco }}

@@ -50,45 +60,71 @@

{{ step.title | transloco }}

- -
-
- - - {{ 'services.celebration.totalTime' | transloco }} - + + +
+ + +
+
+ + {{ 'services.celebration.endpointLabel' | transloco }} +
+
+ {{ baseUrl }}/api/v2/{{ data.serviceName }}/_table + {{ 'services.celebration.endpointHint' | transloco }} +
-
- -
-
{{ 'services.celebration.yourApiKey' | transloco }}
-
- {{ data.apiKey }} - + +
+
+ + {{ 'services.celebration.yourApiKey' | transloco }} +
+
+ {{ data.apiKey }} + +
+
+ + +
+ + {{ 'services.celebration.usageHint' | transloco }}
- - + + +

- {{ 'services.celebration.autoRedirect' | transloco }} + {{ 'services.celebration.autoRedirectTest' | transloco }}

-
\ No newline at end of file +
diff --git a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.scss b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.scss index 224e3c7c..a910e9fd 100644 --- a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.scss +++ b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.scss @@ -6,7 +6,9 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); position: relative; padding: 0; overflow: hidden; - min-height: 480px; + height: 100%; + display: flex; + flex-direction: column; background: linear-gradient(135deg, #f5f3ff 0%, #fff 100%); animation: subtle-entrance 0.4s ease-out; } @@ -39,9 +41,10 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); width: 10px; height: 10px; top: -10px; - animation: confetti-fall calc(3s + var(--confetti-index) * 0.1s) linear infinite; + animation: confetti-fall calc(3s + var(--confetti-index) * 0.1s) linear + infinite; animation-delay: calc(var(--confetti-index) * -0.2s); - + &::before { content: ''; position: absolute; @@ -60,11 +63,11 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); border-radius: 2px; transform: rotate(calc(var(--confetti-index) * 30deg)); } - + &:nth-child(odd) { left: calc(var(--confetti-index) * 6.5%); } - + &:nth-child(even) { right: calc(var(--confetti-index) * 6.5%); } @@ -95,15 +98,31 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); width: 4px; height: 4px; border-radius: 50%; - animation: firework-launch calc(2s + var(--firework-index) * 0.3s) ease-out infinite; + animation: firework-launch calc(2s + var(--firework-index) * 0.3s) ease-out + infinite; animation-delay: calc(var(--firework-index) * 0.5s); - - &:nth-child(1) { left: 20%; background: #7f11e0; } - &:nth-child(2) { left: 40%; background: #ff4081; } - &:nth-child(3) { left: 50%; background: #4caf50; } - &:nth-child(4) { left: 60%; background: #ffc107; } - &:nth-child(5) { left: 80%; background: #2196f3; } - + + &:nth-child(1) { + left: 20%; + background: #7f11e0; + } + &:nth-child(2) { + left: 40%; + background: #ff4081; + } + &:nth-child(3) { + left: 50%; + background: #4caf50; + } + &:nth-child(4) { + left: 60%; + background: #ffc107; + } + &:nth-child(5) { + left: 80%; + background: #2196f3; + } + &::after { content: ''; position: absolute; @@ -114,7 +133,8 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); left: -48px; background: radial-gradient(circle, currentColor 0%, transparent 70%); opacity: 0; - animation: firework-explode calc(2s + var(--firework-index) * 0.3s) ease-out infinite; + animation: firework-explode calc(2s + var(--firework-index) * 0.3s) ease-out + infinite; animation-delay: calc(var(--firework-index) * 0.5s + 0.8s); } } @@ -153,16 +173,38 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); .dialog-content { position: relative; z-index: 2; - padding: 24px; + padding: 20px; max-width: 100%; margin: 0 auto; text-align: center; + overflow-y: auto; + overflow-x: hidden; + flex: 1; + max-height: calc(85vh - 40px); + + /* Custom scrollbar */ + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: rgba(127, 17, 224, 0.05); + } + + &::-webkit-scrollbar-thumb { + background: rgba(127, 17, 224, 0.2); + border-radius: 3px; + + &:hover { + background: rgba(127, 17, 224, 0.3); + } + } } // Success Header .success-header { text-align: center; - margin-bottom: 24px; + margin-bottom: 16px; animation: fadeInDown 0.6s ease-out; } @@ -171,7 +213,7 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); width: 64px; height: 64px; margin: 0 auto 16px; - + .rocket-icon { position: absolute; top: 50%; @@ -182,7 +224,7 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); z-index: 2; animation: rocket-launch 2s ease-in-out infinite; } - + .success-circle { position: absolute; width: 100%; @@ -195,7 +237,8 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); } @keyframes rocket-launch { - 0%, 100% { + 0%, + 100% { transform: translate(-50%, -50%) translateY(0); } 50% { @@ -204,7 +247,8 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); } @keyframes pulse-circle { - 0%, 100% { + 0%, + 100% { transform: scale(1); opacity: 0.1; } @@ -215,16 +259,16 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); } .celebration-title { - font-size: 24px; + font-size: 20px; font-weight: 600; color: #333; - margin: 0 0 8px; + margin: 0 0 6px; animation: bounce-in 0.8s ease-out; text-align: center; } .celebration-subtitle { - font-size: 15px; + font-size: 14px; color: #666; margin: 0; text-align: center; @@ -232,16 +276,16 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); // Steps Timeline .steps-container { - margin: 24px 0; + margin: 12px 0; text-align: left; - padding: 0 10px; + padding: 0 8px; } .steps-title { - font-size: 16px; + font-size: 14px; font-weight: 500; color: #333; - margin-bottom: 20px; + margin-bottom: 12px; text-align: center; } @@ -256,22 +300,22 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); position: relative; display: flex; align-items: flex-start; - margin-bottom: 20px; + margin-bottom: 12px; opacity: 0; transform: translateX(-20px); transition: all 0.5s ease-out; - + &.revealed { opacity: 1; transform: translateX(0); } - + &.pulse-animation { .step-icon { animation: icon-pulse 0.6s ease-out; } } - + .step-connector { position: absolute; left: -35px; @@ -335,104 +379,170 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); font-size: 12px; color: #4caf50; font-weight: 500; - + .timing-icon { font-size: 12px; } } -// Performance Summary -.performance-summary { - text-align: center; - margin: 20px 0; +// API Connection Section +.api-connection-section { + margin: 12px auto; + padding: 14px; + background: linear-gradient(135deg, #f8f5ff 0%, #f5f5f5 100%); + border: 1px solid rgba(127, 17, 224, 0.1); + border-radius: 12px; animation: slideUp 0.5s ease-out; + max-width: 480px; } -.performance-badge { - display: inline-flex; - align-items: center; - gap: 6px; - padding: 10px 20px; - background: linear-gradient(135deg, #4caf50 0%, #388e3c 100%); - border-radius: 20px; - color: white; +.endpoint-preview { + margin-bottom: 12px; + padding-bottom: 10px; + border-bottom: 1px solid rgba(127, 17, 224, 0.1); +} + +.endpoint-label { + font-size: 14px; font-weight: 500; - box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3); - - .performance-icon { + color: #333; + margin-bottom: 10px; + display: flex; + align-items: center; + gap: 8px; + + .endpoint-icon { + color: #7f11e0; font-size: 16px; } - - .performance-text { - font-size: 14px; +} + +.endpoint-display { + position: relative; + + code { + display: block; + padding: 12px 16px; + background: white; + border: 1px solid #e0e0e0; + border-radius: 6px; + font-family: 'Courier New', monospace; + font-size: 13px; + color: #2196f3; + overflow-x: auto; + margin-bottom: 4px; + } + + .endpoint-hint { + font-size: 11px; + color: #999; + font-style: italic; } } -// API Key Section -.api-key-section { - margin: 20px auto; - padding: 14px; - background: #f5f5f5; - border-radius: 8px; - animation: slideUp 0.5s ease-out; - max-width: 450px; +.api-key-subsection { + margin-bottom: 10px; } .api-key-label { - font-size: 13px; - color: #666; - margin-bottom: 8px; - text-align: left; + font-size: 14px; + font-weight: 500; + color: #333; + margin-bottom: 10px; + display: flex; + align-items: center; + gap: 8px; + + .key-icon { + color: #ff9800; + font-size: 16px; + } } .api-key-display { display: flex; align-items: center; gap: 8px; - + code { flex: 1; - padding: 8px 12px; + padding: 10px 14px; background: white; border: 1px solid #e0e0e0; - border-radius: 4px; + border-radius: 6px; font-family: monospace; font-size: 14px; + color: #333; overflow-x: auto; } - + button { + transition: all 0.2s ease; + fa-icon { font-size: 16px; color: #666; + transition: color 0.2s ease; } - + &:hover fa-icon { color: #7f11e0; } } } +.usage-hint { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 10px; + background: rgba(33, 150, 243, 0.05); + border-radius: 6px; + font-size: 12px; + color: #555; + line-height: 1.4; + + .info-icon { + color: #2196f3; + font-size: 14px; + margin-top: 1px; + } +} + // Dialog Actions .dialog-actions { text-align: center; - margin-top: 24px; + margin-top: 12px; + padding-bottom: 8px; animation: fadeIn 0.5s ease-out; } -.explore-button { +.test-api-button { padding: 10px 28px; font-size: 15px; - text-transform: uppercase; - letter-spacing: 0.5px; - + font-weight: 500; + letter-spacing: 0.3px; + margin-bottom: 10px; + min-width: 200px; + .button-icon { margin-right: 8px; + font-size: 18px; } - + .countdown { margin-left: 8px; - opacity: 0.8; + opacity: 0.7; + font-size: 14px; + } +} + +.explore-later-button { + font-size: 14px; + color: #666; + + &:hover { + background: rgba(0, 0, 0, 0.04); } } @@ -494,25 +604,35 @@ $df-purple-palette: mat.define-palette(theme.$df-purple-palette); .celebration-dialog { background: linear-gradient(135deg, #1a1a2e 0%, #0f0f1e 100%); } - + .celebration-title, .steps-title, .step-title { color: rgba(255, 255, 255, 0.87); } - + .celebration-subtitle, .step-description { color: rgba(255, 255, 255, 0.6); } - - .api-key-section { - background: rgba(255, 255, 255, 0.05); - + + .api-connection-section { + background: linear-gradient(135deg, rgba(127, 17, 224, 0.05) 0%, rgba(255, 255, 255, 0.03) 100%); + border-color: rgba(127, 17, 224, 0.2); + code { background: rgba(255, 255, 255, 0.1); border-color: rgba(255, 255, 255, 0.2); color: rgba(255, 255, 255, 0.87); } + + .endpoint-display code { + color: #5eb8ff; + } + + .usage-hint { + background: rgba(33, 150, 243, 0.08); + color: rgba(255, 255, 255, 0.7); + } } -} \ No newline at end of file +} diff --git a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.ts b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.ts index c25a9603..7bfe00e7 100644 --- a/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.ts +++ b/src/app/shared/components/df-celebration-dialog/df-celebration-dialog.component.ts @@ -18,6 +18,9 @@ import { faBolt, faDatabase, faCopy, + faCheck, + faFlask, + faInfoCircle, } from '@fortawesome/free-solid-svg-icons'; import { Router } from '@angular/router'; import { interval, Subject, takeUntil } from 'rxjs'; @@ -45,7 +48,7 @@ export interface CelebrationDialogData { }) export class DfCelebrationDialogComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); - + // Icons faCheckCircle = faCheckCircle; faRocket = faRocket; @@ -54,12 +57,17 @@ export class DfCelebrationDialogComponent implements OnInit, OnDestroy { faBolt = faBolt; faDatabase = faDatabase; faCopy = faCopy; + faCheck = faCheck; + faFlask = faFlask; + faInfoCircle = faInfoCircle; // Animation states showConfetti = true; currentStep = -1; allStepsRevealed = false; countdown = 15; + apiKeyCopied = false; + baseUrl = window.location.origin; // API creation steps steps = [ @@ -101,7 +109,7 @@ export class DfCelebrationDialogComponent implements OnInit, OnDestroy { ngOnInit(): void { // Start revealing steps one by one this.revealSteps(); - + // Start countdown after all steps are revealed setTimeout(() => { this.startCountdown(); @@ -117,12 +125,15 @@ export class DfCelebrationDialogComponent implements OnInit, OnDestroy { // Reveal each step with a delay const stepDelay = 500; this.steps.forEach((_, index) => { - setTimeout(() => { - this.currentStep = index; - if (index === this.steps.length - 1) { - this.allStepsRevealed = true; - } - }, stepDelay * (index + 1)); + setTimeout( + () => { + this.currentStep = index; + if (index === this.steps.length - 1) { + this.allStepsRevealed = true; + } + }, + stepDelay * (index + 1) + ); }); } @@ -145,6 +156,15 @@ export class DfCelebrationDialogComponent implements OnInit, OnDestroy { copyApiKey(): void { if (this.data.apiKey) { navigator.clipboard.writeText(this.data.apiKey); + this.apiKeyCopied = true; + setTimeout(() => { + this.apiKeyCopied = false; + }, 2000); } } -} \ No newline at end of file + + skipToHome(): void { + this.dialogRef.close(); + this.router.navigate(['/home']); + } +} diff --git a/src/app/shared/components/df-security-config/df-security-config.component.ts b/src/app/shared/components/df-security-config/df-security-config.component.ts index 2dd0935b..69b73773 100644 --- a/src/app/shared/components/df-security-config/df-security-config.component.ts +++ b/src/app/shared/components/df-security-config/df-security-config.component.ts @@ -444,6 +444,7 @@ export class DfSecurityConfigComponent implements OnInit { const dialogRef = this.dialog.open(DfCelebrationDialogComponent, { width: '550px', maxWidth: '90vw', + maxHeight: '85vh', disableClose: true, panelClass: 'celebration-dialog-container', data: { @@ -452,7 +453,7 @@ export class DfSecurityConfigComponent implements OnInit { isFirstTime: true, }, }); - + // Dialog will handle navigation to API docs when closed } else { // Navigate to API docs directly for experienced users diff --git a/src/assets/i18n/services/en.json b/src/assets/i18n/services/en.json index d3839713..b5c6fa5f 100644 --- a/src/assets/i18n/services/en.json +++ b/src/assets/i18n/services/en.json @@ -50,10 +50,14 @@ "description": "Created a secure API key for authentication" } }, - "totalTime": "Total time: < 1 second", - "yourApiKey": "Your API Key:", + "endpointLabel": "Your API Endpoint:", + "endpointHint": "(lists all tables)", + "yourApiKey": "Authentication Key:", "copyKey": "Copy API Key", - "exploreApi": "Explore Your API", - "autoRedirect": "You'll be automatically redirected to API documentation..." + "keyCopied": "Copied!", + "usageHint": "Add the API key to the 'X-DreamFactory-Api-Key' header in your requests", + "testYourApi": "Test Your API Now", + "exploreLater": "I'll explore later", + "autoRedirectTest": "Redirecting to API testing playground..." } } diff --git a/src/styles.scss b/src/styles.scss index 544dab8b..1c3348c5 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -245,7 +245,7 @@ a { border-radius: 12px !important; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3) !important; } - + .mat-mdc-dialog-surface { border-radius: 12px !important; overflow: hidden !important;