From 258d2ff5a8faf4d69c29d29f518a12fb72d17374 Mon Sep 17 00:00:00 2001 From: Kevin McGahey Date: Sun, 29 Jun 2025 16:31:01 -0700 Subject: [PATCH 1/2] AI tab addition --- .gitignore | 2 + src/app/ai/ai.component.ts | 211 ++++++++++++++++++ src/app/routes.ts | 7 + .../df-side-nav/df-side-nav.component.html | 1 + .../df-side-nav/df-side-nav.component.scss | 79 +++++++ src/app/shared/types/routes.ts | 1 + src/app/shared/utilities/route.ts | 3 +- src/assets/i18n/en.json | 4 + src/assets/img/nav/ai.svg | 14 ++ src/environments/environment.ts | 1 + 10 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 src/app/ai/ai.component.ts create mode 100644 src/assets/img/nav/ai.svg diff --git a/.gitignore b/.gitignore index 7a4a8630..58f8ab12 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ testem.log # System files .DS_Store Thumbs.db + +.config/ diff --git a/src/app/ai/ai.component.ts b/src/app/ai/ai.component.ts new file mode 100644 index 00000000..5d0e4e2e --- /dev/null +++ b/src/app/ai/ai.component.ts @@ -0,0 +1,211 @@ +import { Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute } from '@angular/router'; +import { DfPaywallComponent } from '../shared/components/df-paywall/df-paywall.component'; +import { NgIf } from '@angular/common'; + +@Component({ + selector: 'app-ai', + standalone: true, + imports: [CommonModule, DfPaywallComponent, NgIf], + template: ` +
+
+
+

AI Gateway Data Platform

+
+

+ Unlock the power of AI with your data! Our upcoming AI capabilities will enable you to: +

+
    +
  • Secure Dataset Exposure: Safely expose your datasets to AI clients with full RBAC protections
  • +
  • 🔐 Enterprise-Grade Security: Maintain complete control over data access and permissions
  • +
  • 🚀 Seamless Integration: Connect popular AI platforms and tools directly to your DreamFactory APIs
  • +
  • 📊 Intelligent Analytics: Generate insights and recommendations powered by machine learning
  • +
+
+

🎯 Ready to Get Started?

+

Contact us below to join our exclusive AI beta program and be among the first to experience these cutting-edge capabilities!

+
+
+
+
+ +
+ +
+

AI Assistant

+

Welcome to the AI section! This is where AI-powered features will be implemented.

+
+
+

Smart Analytics

+

AI-powered data insights and analytics

+
+
+

Automated Tasks

+

Intelligent automation and task management

+
+
+

Predictive Modeling

+

Advanced machine learning predictions

+
+
+
+
+ `, + styles: [` + .ai-paywall-container { + min-height: 100vh; + background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); + } + + .ai-intro-section { + padding: 3rem 2rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + position: relative; + overflow: hidden; + } + + .ai-intro-section::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: url('data:image/svg+xml,'); + opacity: 0.3; + } + + .ai-intro-content { + max-width: 800px; + margin: 0 auto; + position: relative; + z-index: 1; + } + + .ai-title { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 1.5rem; + text-align: center; + color: #000; + } + + @keyframes rainbow-text { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + } + + .lead-text { + font-size: 1.2rem; + font-weight: 500; + margin-bottom: 2rem; + text-align: center; + opacity: 0.95; + } + + .feature-list { + list-style: none; + padding: 0; + margin: 2rem 0; + } + + .feature-list li { + padding: 0.8rem 0; + font-size: 1.1rem; + display: flex; + align-items: center; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); + opacity: 0.9; + } + + .feature-list li:last-child { + border-bottom: none; + } + + .beta-callout { + background: rgba(255, 255, 255, 0.1); + padding: 1.5rem; + border-radius: 12px; + margin-top: 2rem; + text-align: center; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.2); + } + + .beta-callout h3 { + margin-bottom: 0.5rem; + font-size: 1.3rem; + color: #ffd700; + } + + .beta-callout p { + margin: 0; + font-size: 1rem; + opacity: 0.9; + } + + .ai-container { + padding: 2rem; + max-width: 1200px; + margin: 0 auto; + } + + h1 { + color: #333; + margin-bottom: 1rem; + background: linear-gradient(45deg, #dc143c, #ff4500, #ffa500, #32cd32, #1e90ff, #8a2be2); + background-size: 300% 300%; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + animation: rainbow-text 3s ease-in-out infinite; + font-weight: 700; + text-shadow: 0 0 15px rgba(0, 0, 0, 0.2); + filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.1)); + } + + .ai-content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + margin-top: 2rem; + } + + .feature-card { + background: #f8f9fa; + padding: 1.5rem; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transition: transform 0.2s ease; + } + + .feature-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0,0,0,0.15); + } + + .feature-card h3 { + margin-bottom: 0.5rem; + color: #333; + } + + .feature-card p { + color: #666; + line-height: 1.5; + } + `] +}) +export class AiComponent { + paywall = false; + + constructor(private activatedRoute: ActivatedRoute) { + this.activatedRoute.data.subscribe(({ showPaywall }) => { + if (showPaywall) { + this.paywall = true; + } + }); + } +} \ No newline at end of file diff --git a/src/app/routes.ts b/src/app/routes.ts index ae260047..7c6f1e02 100644 --- a/src/app/routes.ts +++ b/src/app/routes.ts @@ -799,6 +799,13 @@ export const routes: Routes = [ ], canActivate: [loggedInGuard, licenseGuard], }, + { + path: ROUTES.AI, + loadComponent: () => + import('./ai/ai.component').then(m => m.AiComponent), + canActivate: [loggedInGuard, licenseGuard], + data: { showPaywall: true }, + }, { path: ROUTES.PROFILE, loadComponent: () => diff --git a/src/app/shared/components/df-side-nav/df-side-nav.component.html b/src/app/shared/components/df-side-nav/df-side-nav.component.html index c8ded1a4..2a1e316e 100644 --- a/src/app/shared/components/df-side-nav/df-side-nav.component.html +++ b/src/app/shared/components/df-side-nav/df-side-nav.component.html @@ -154,6 +154,7 @@

class="nav-item" [class.active]="isActive(item)" [class.commercial-feature]="isFeatureLocked(item.path, licenseType)" + [class.ai-nav-item]="item.path === '/ai'" (click)="handleNavClick(item)"> diff --git a/src/app/shared/components/df-side-nav/df-side-nav.component.scss b/src/app/shared/components/df-side-nav/df-side-nav.component.scss index 3d3ebe4f..0a6055ae 100644 --- a/src/app/shared/components/df-side-nav/df-side-nav.component.scss +++ b/src/app/shared/components/df-side-nav/df-side-nav.component.scss @@ -159,6 +159,85 @@ $red-palette: mat.define-palette(mat.$red-palette); ::ng-deep .mat-mdc-button-touch-target { background-color: #f6f2fa; } + + // Special styling for AI navigation item + &.ai-nav-item { + position: relative; + overflow: hidden; + + &::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, + transparent, + rgba(220, 20, 60, 0.15), + rgba(255, 69, 0, 0.15), + rgba(255, 165, 0, 0.15), + rgba(50, 205, 50, 0.15), + rgba(30, 144, 255, 0.15), + rgba(138, 43, 226, 0.15), + transparent + ); + animation: rainbow-slide 3s ease-in-out infinite; + } + + span { + background: linear-gradient(45deg, #dc143c, #ff4500, #ffa500, #32cd32, #1e90ff, #8a2be2); + background-size: 300% 300%; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + animation: rainbow-text 2s ease-in-out infinite; + font-weight: 700; + text-shadow: 0 0 15px rgba(0, 0, 0, 0.3); + filter: drop-shadow(0 0 8px rgba(0, 0, 0, 0.2)); + } + + img { + filter: hue-rotate(0deg) saturate(2) brightness(0.8) contrast(1.3); + animation: rainbow-icon 4s linear infinite; + drop-shadow: 0 0 6px rgba(0, 0, 0, 0.3); + } + + &:hover { + &::before { + animation-duration: 1s; + } + + span { + animation-duration: 1s; + } + + img { + animation-duration: 2s; + } + } + } + + @keyframes rainbow-slide { + 0% { left: -100%; } + 50% { left: 100%; } + 100% { left: -100%; } + } + + @keyframes rainbow-text { + 0%, 100% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + } + + @keyframes rainbow-icon { + 0% { filter: hue-rotate(0deg) saturate(2) brightness(0.8) contrast(1.3) drop-shadow(0 0 6px rgba(220, 20, 60, 0.4)); } + 16.66% { filter: hue-rotate(60deg) saturate(2.2) brightness(0.7) contrast(1.4) drop-shadow(0 0 6px rgba(255, 69, 0, 0.4)); } + 33.33% { filter: hue-rotate(120deg) saturate(2.4) brightness(0.6) contrast(1.5) drop-shadow(0 0 6px rgba(255, 165, 0, 0.4)); } + 50% { filter: hue-rotate(180deg) saturate(2.2) brightness(0.7) contrast(1.4) drop-shadow(0 0 6px rgba(50, 205, 50, 0.4)); } + 66.66% { filter: hue-rotate(240deg) saturate(2) brightness(0.8) contrast(1.3) drop-shadow(0 0 6px rgba(30, 144, 255, 0.4)); } + 83.33% { filter: hue-rotate(300deg) saturate(2.2) brightness(0.7) contrast(1.4) drop-shadow(0 0 6px rgba(138, 43, 226, 0.4)); } + 100% { filter: hue-rotate(360deg) saturate(2) brightness(0.8) contrast(1.3) drop-shadow(0 0 6px rgba(220, 20, 60, 0.4)); } + } &.active { ::ng-deep .mat-mdc-button-touch-target { background-color: #e3dfff; diff --git a/src/app/shared/types/routes.ts b/src/app/shared/types/routes.ts index 768263d9..3794b4b8 100644 --- a/src/app/shared/types/routes.ts +++ b/src/app/shared/types/routes.ts @@ -16,6 +16,7 @@ export enum ROUTES { QUICKSTART = 'quickstart', RESOURCES = 'resources', DOWNLOAD = 'download', + AI = 'ai', API_CONNECTIONS = 'api-connections', API_TYPES = 'api-types', DATABASE = 'database', diff --git a/src/app/shared/utilities/route.ts b/src/app/shared/utilities/route.ts index 3ea19119..5b04e1c1 100644 --- a/src/app/shared/utilities/route.ts +++ b/src/app/shared/utilities/route.ts @@ -15,6 +15,7 @@ const filteredFromNav = [ const navIcons = [ 'home', + 'ai', 'admin-settings', 'api-connections', 'api-security', @@ -62,7 +63,7 @@ export function accessibleRoutes( navs: Array