🧠 Add AI Brand Strategist embedded interface with Quantum Tasks header

- Create dedicated template with header + JotForm iframe
- Add ai_brand_strategist_view() and ai_brand_strategist_access() functions
- Add dedicated URL routes /ai-brand-strategist/ and /ai-brand-strategist/access/
- Update marketplace buttons to use dedicated routes for consistent UX
- Both CyberSec Career Navigator and AI Brand Strategist now show embedded forms
- Follows established direct access agent architecture pattern

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude 2025-08-04 23:36:35 +05:30
parent 6fae2686c5
commit d8b8420319
4 changed files with 149 additions and 0 deletions

View File

@ -95,6 +95,10 @@
<a href="{% url 'agents:career_navigator_access' %}" class="try-btn career-nav-btn">
🎓 Try Now →
</a>
{% elif agent.slug == 'ai-brand-strategist' %}
<a href="{% url 'agents:ai_brand_strategist_access' %}" class="try-btn">
🧠 Try Now →
</a>
{% else %}
<a href="{% url 'agents:detail' agent.slug %}" class="try-btn">Try Now →</a>
{% endif %}
@ -103,6 +107,10 @@
<a href="{% url 'authentication:login' %}?next={% url 'agents:career_navigator_access' %}" class="try-btn login-required" style="width: 100%;">
🔐 Login to Try
</a>
{% elif agent.slug == 'ai-brand-strategist' %}
<a href="{% url 'authentication:login' %}?next={% url 'agents:ai_brand_strategist_access' %}" class="try-btn login-required" style="width: 100%;">
🔐 Login to Try
</a>
{% else %}
<a href="{% url 'authentication:login' %}?next={% url 'agents:detail' agent.slug %}" class="try-btn login-required" style="width: 100%;">
🔐 Login to Try

View File

@ -10,6 +10,8 @@ urlpatterns = [
# Direct access routes
path('career-navigator/', views.career_navigator_view, name='career_navigator'),
path('career-navigator/access/', views.career_navigator_access, name='career_navigator_access'),
path('ai-brand-strategist/', views.ai_brand_strategist_view, name='ai_brand_strategist'),
path('ai-brand-strategist/access/', views.ai_brand_strategist_access, name='ai_brand_strategist_access'),
# API endpoints - specific URLs first to avoid slug conflicts
path('api/execute/', views.execute_agent, name='execute_agent'),

View File

@ -289,6 +289,102 @@ def career_navigator_view(request):
return render(request, 'career_navigator.html', context)
def ai_brand_strategist_view(request):
"""Display the AI Brand Strategist form page"""
if not request.user.is_authenticated:
# Clear any existing messages to prevent confusion
storage = messages.get_messages(request)
storage.used = True
messages.error(request, 'Please login to access the AI Brand Strategist.')
return redirect('authentication:login')
# Get the AI Brand Strategist agent
try:
agent = Agent.objects.get(slug='ai-brand-strategist', is_active=True)
except Agent.DoesNotExist:
messages.error(request, 'AI Brand Strategist is currently unavailable.')
return redirect('agents:marketplace')
# Check if user has a recent execution (within last 2 hours) or just redirect to payment
from django.utils import timezone
from datetime import timedelta
recent_execution = AgentExecution.objects.filter(
agent=agent,
user=request.user,
status='completed',
created_at__gte=timezone.now() - timedelta(hours=2)
).first()
if not recent_execution:
messages.info(request, 'Please click "Try Now" to access your AI Brand Strategist consultation.')
return redirect('agents:marketplace')
context = {
'agent': agent,
'form_url': agent.webhook_url,
'user_balance': request.user.wallet_balance,
'execution': recent_execution
}
return render(request, 'ai_brand_strategist.html', context)
def ai_brand_strategist_access(request):
"""Handle Try Now button click - charge wallet and redirect to form"""
if not request.user.is_authenticated:
# Clear any existing messages to prevent confusion
storage = messages.get_messages(request)
storage.used = True
messages.error(request, 'Please login to access the AI Brand Strategist.')
return redirect('authentication:login')
# Get the AI Brand Strategist agent
try:
agent = Agent.objects.get(slug='ai-brand-strategist', is_active=True)
except Agent.DoesNotExist:
messages.error(request, 'AI Brand Strategist is currently unavailable.')
return redirect('agents:marketplace')
# Check if user has sufficient balance
if not request.user.has_sufficient_balance(agent.price):
messages.error(request, f'Insufficient balance! You need {agent.price} AED to access the AI Brand Strategist.')
return redirect('wallet:wallet')
# Deduct fee from user wallet
success = request.user.deduct_balance(
agent.price,
f'{agent.name} - Direct Access',
agent.slug
)
if not success:
messages.error(request, 'Failed to process payment. Please try again.')
return redirect('agents:marketplace')
# Create execution record for tracking
execution = AgentExecution.objects.create(
agent=agent,
user=request.user,
input_data={'action': 'direct_access', 'source': 'try_now_button'},
fee_charged=agent.price,
status='completed',
output_data={
'type': 'direct_access',
'message': f'Direct access granted to {agent.name}',
'access_method': 'try_now_button'
},
completed_at=timezone.now()
)
# Success message and redirect to form
if agent.price > 0:
messages.success(request, f'Welcome to your {agent.name} consultation.')
else:
messages.success(request, f'Welcome to your {agent.name} consultation.')
return redirect('agents:ai_brand_strategist')
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def execution_list(request):

View File

@ -0,0 +1,43 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}AI Brand Strategist - Quantum Tasks AI{% endblock %}
{% block extra_css %}
<style>
/* Override main-container for full-width iframe */
.main-container {
max-width: none;
padding: 0;
height: calc(100vh - 80px); /* Account for header height */
}
.iframe-container {
width: 100%;
height: 100%;
}
.iframe-container iframe {
width: 100%;
height: 100%;
border: none;
display: block;
}
/* Hide footer for this page */
.footer {
display: none !important;
}
</style>
{% endblock %}
{% block content %}
<div class="iframe-container">
<iframe
src="{{ form_url }}"
frameborder="0"
scrolling="auto"
title="AI Brand Strategist">
</iframe>
</div>
{% endblock %}