diff --git a/ai/__pycache__/__init__.cpython-311.pyc b/ai/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000..9beeae7
Binary files /dev/null and b/ai/__pycache__/__init__.cpython-311.pyc differ
diff --git a/ai/__pycache__/local_ai_api.cpython-311.pyc b/ai/__pycache__/local_ai_api.cpython-311.pyc
new file mode 100644
index 0000000..ae12bda
Binary files /dev/null and b/ai/__pycache__/local_ai_api.cpython-311.pyc differ
diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc
index a5ed392..6fd5d9f 100644
Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ
diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc
index e061640..d2cfb77 100644
Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ
diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc
index 5a69659..0e2453b 100644
Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ
diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc
index 2a36fd6..d2627c4 100644
Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ
diff --git a/core/admin.py b/core/admin.py
index 8c38f3f..428ec85 100644
--- a/core/admin.py
+++ b/core/admin.py
@@ -1,3 +1,17 @@
from django.contrib import admin
+from .models import Organization, Profile, ChatMessage
-# Register your models here.
+@admin.register(Organization)
+class OrganizationAdmin(admin.ModelAdmin):
+ list_display = ('name', 'slug', 'created_at')
+ prepopulated_fields = {'slug': ('name',)}
+
+@admin.register(Profile)
+class ProfileAdmin(admin.ModelAdmin):
+ list_display = ('user', 'organization', 'role')
+ list_filter = ('role', 'organization')
+
+@admin.register(ChatMessage)
+class ChatMessageAdmin(admin.ModelAdmin):
+ list_display = ('user', 'organization', 'created_at')
+ readonly_fields = ('created_at',)
\ No newline at end of file
diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py
new file mode 100644
index 0000000..bd08f28
--- /dev/null
+++ b/core/migrations/0001_initial.py
@@ -0,0 +1,46 @@
+# Generated by Django 5.2.7 on 2026-01-21 19:24
+
+import django.db.models.deletion
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Organization',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=255)),
+ ('slug', models.SlugField(unique=True)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='ChatMessage',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('message', models.TextField()),
+ ('response', models.TextField()),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='core.organization')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Profile',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('role', models.CharField(choices=[('SUPER_ADMIN', 'Super Admin'), ('ORG_ADMIN', 'Organization Admin'), ('USER', 'User')], default='USER', max_length=20)),
+ ('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='members', to='core.organization')),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ ]
diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc
new file mode 100644
index 0000000..f26db05
Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ
diff --git a/core/models.py b/core/models.py
index 71a8362..8cbec7a 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1,3 +1,44 @@
from django.db import models
+from django.contrib.auth.models import User
+from django.db.models.signals import post_save
+from django.dispatch import receiver
-# Create your models here.
+class Organization(models.Model):
+ name = models.CharField(max_length=255)
+ slug = models.SlugField(unique=True)
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return self.name
+
+class Profile(models.Model):
+ ROLE_CHOICES = (
+ ('SUPER_ADMIN', 'Super Admin'),
+ ('ORG_ADMIN', 'Organization Admin'),
+ ('USER', 'User'),
+ )
+ user = models.OneToOneField(User, on_delete=models.CASCADE)
+ organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, null=True, blank=True, related_name='members')
+ role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='USER')
+
+ def __str__(self):
+ return f"{self.user.username} - {self.role}"
+
+@receiver(post_save, sender=User)
+def create_user_profile(sender, instance, created, **kwargs):
+ if created:
+ Profile.objects.create(user=instance)
+
+@receiver(post_save, sender=User)
+def save_user_profile(sender, instance, **kwargs):
+ instance.profile.save()
+
+class ChatMessage(models.Model):
+ user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
+ organization = models.ForeignKey(Organization, on_delete=models.CASCADE, null=True, blank=True)
+ message = models.TextField()
+ response = models.TextField()
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return f"Chat at {self.created_at}"
\ No newline at end of file
diff --git a/core/templates/base.html b/core/templates/base.html
index 1e7e5fb..db59b26 100644
--- a/core/templates/base.html
+++ b/core/templates/base.html
@@ -1,25 +1,67 @@
-
-
- {% block title %}Knowledge Base{% endblock %}
- {% if project_description %}
-
-
-
- {% endif %}
- {% if project_image_url %}
-
-
- {% endif %}
- {% load static %}
-
- {% block head %}{% endblock %}
+
+
+ {% block title %}AIBiz Platform - AI-Driven B2B SaaS{% endblock %}
+ {% if project_description %}
+
+
+
+ {% endif %}
+ {% if project_image_url %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+ {% load static %}
+
+ {% block head %}{% endblock %}
+
+
-
- {% block content %}{% endblock %}
+
+ {% block content %}{% endblock %}
+
+
+
+
+
-
-
+
\ No newline at end of file
diff --git a/core/templates/core/index.html b/core/templates/core/index.html
index faec813..6469d09 100644
--- a/core/templates/core/index.html
+++ b/core/templates/core/index.html
@@ -1,145 +1,128 @@
{% extends "base.html" %}
-
-{% block title %}{{ project_name }}{% endblock %}
-
-{% block head %}
-
-
-
-
-{% endblock %}
+{% load static %}
{% block content %}
-
-
-
Analyzing your requirements and generating your app…
-
-
Loading…
+
+
+
+
+
Enterprise Ready AI
+
Scale Your Business with Intelligent Workflows
+
The ultimate AI-driven SaaS platform for multitenant organizations. Manage teams, automate documents, and chat with your business intelligence.
+
+
+
+
+
+
+
+
+ Hello! I'm your AIBiz Assistant. How can I help you optimize your business today?
+
+
+
+
+
+
+
- AppWizzy AI is collecting your requirements and applying the first changes.
- This page will refresh automatically as the plan is implemented.
-
- Runtime: Django {{ django_version }} · Python {{ python_version }}
- — UTC {{ current_time|date:"Y-m-d H:i:s" }}
-
-
-
-
-{% endblock %}
\ No newline at end of file
+
+
+
+
+
+
Everything You Need to Succeed
+
Powerful tools designed for the modern B2B ecosystem.
+
+
+
+
+
🏢
+
Multitenancy
+
Built-in organization management with isolated data and custom roles.
+
+
+
+
+
🤖
+
AI Chat
+
Context-aware assistant trained on your business data and workflows.
+
+
+
+
+
📄
+
Doc Ingestion
+
Automated summarization and data extraction from complex business documents.
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/core/urls.py b/core/urls.py
index 6299e3d..fd499c3 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -1,7 +1,7 @@
from django.urls import path
-
-from .views import home
+from .views import home, ai_chat
urlpatterns = [
path("", home, name="home"),
-]
+ path("api/ai-chat/", ai_chat, name="ai_chat"),
+]
\ No newline at end of file
diff --git a/core/views.py b/core/views.py
index c9aed12..619c0b7 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,25 +1,59 @@
import os
import platform
-
+import json
from django import get_version as django_version
from django.shortcuts import render
+from django.http import JsonResponse
from django.utils import timezone
-
+from django.views.decorators.csrf import csrf_exempt
+from ai.local_ai_api import LocalAIApi
+from .models import ChatMessage, Organization
def home(request):
- """Render the landing screen with loader and environment details."""
- host_name = request.get_host().lower()
- agent_brand = "AppWizzy" if host_name == "appwizzy.com" else "Flatlogic"
+ """Render the landing screen with AI Chat Assistant."""
now = timezone.now()
-
+
context = {
- "project_name": "New Style",
- "agent_brand": agent_brand,
+ "project_name": "AIBiz Platform",
"django_version": django_version(),
"python_version": platform.python_version(),
"current_time": now,
- "host_name": host_name,
- "project_description": os.getenv("PROJECT_DESCRIPTION", ""),
+ "project_description": os.getenv("PROJECT_DESCRIPTION", "AI-Driven B2B SaaS Platform for modern enterprises."),
"project_image_url": os.getenv("PROJECT_IMAGE_URL", ""),
}
return render(request, "core/index.html", context)
+
+@csrf_exempt
+def ai_chat(request):
+ if request.method == "POST":
+ try:
+ data = json.loads(request.body)
+ user_message = data.get("message")
+
+ if not user_message:
+ return JsonResponse({"error": "No message provided"}, status=400)
+
+ # Construct the prompt for the AI
+ messages = [
+ {"role": "system", "content": "You are AIBiz Assistant, an expert in business workflows, SaaS, and AI automation. Help the user with their business questions concisely and professionally."},
+ {"role": "user", "content": user_message},
+ ]
+
+ response = LocalAIApi.create_response(
+ {"input": messages},
+ {"poll_interval": 2, "poll_timeout": 60}
+ )
+
+ if response.get("success"):
+ ai_reply = LocalAIApi.extract_text(response) or "I'm sorry, I couldn't generate a response."
+
+ # Save message to DB if user is authenticated (optional for landing)
+ # ChatMessage.objects.create(message=user_message, response=ai_reply)
+
+ return JsonResponse({"reply": ai_reply})
+ else:
+ return JsonResponse({"error": response.get("error", "AI service error")}, status=500)
+ except Exception as e:
+ return JsonResponse({"error": str(e)}, status=500)
+
+ return JsonResponse({"error": "Invalid request"}, status=400)
\ No newline at end of file
diff --git a/static/css/custom.css b/static/css/custom.css
index 925f6ed..0ccb83f 100644
--- a/static/css/custom.css
+++ b/static/css/custom.css
@@ -1,4 +1,104 @@
-/* Custom styles for the application */
-body {
- font-family: system-ui, -apple-system, sans-serif;
+:root {
+ --primary-color: #2563eb;
+ --secondary-color: #0f172a;
+ --accent-color: #10b981;
+ --bg-light: #f8fafc;
+ --navy: #0f172a;
}
+
+body {
+ font-family: 'Plus Jakarta Sans', sans-serif;
+ color: #334155;
+ background-color: var(--bg-light);
+}
+
+.text-primary { color: var(--primary-color) !important; }
+.btn-primary {
+ background-color: var(--primary-color);
+ border-color: var(--primary-color);
+ font-weight: 600;
+}
+.btn-primary:hover {
+ background-color: #1d4ed8;
+}
+
+.bg-navy { background-color: var(--navy); }
+
+/* Hero Section */
+.hero-section {
+ padding: 100px 0;
+ background: radial-gradient(circle at top right, rgba(37, 99, 235, 0.05), transparent),
+ radial-gradient(circle at bottom left, rgba(16, 185, 129, 0.05), transparent);
+}
+
+.glass-card {
+ background: rgba(255, 255, 255, 0.7);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ border-radius: 20px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
+}
+
+/* Chat Assistant Widget */
+.chat-container {
+ height: 400px;
+ display: flex;
+ flex-direction: column;
+}
+
+.chat-messages {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding: 15px;
+}
+
+.chat-bubble {
+ padding: 10px 15px;
+ border-radius: 15px;
+ margin-bottom: 10px;
+ max-width: 85%;
+ font-size: 0.9rem;
+}
+
+.bubble-ai {
+ background-color: #f1f5f9;
+ color: #1e293b;
+ align-self: flex-start;
+}
+
+.bubble-user {
+ background-color: var(--primary-color);
+ color: white;
+ align-self: flex-end;
+ margin-left: auto;
+}
+
+.chat-input-area {
+ padding: 15px;
+ border-top: 1px solid #e2e8f0;
+}
+
+.feature-card {
+ padding: 30px;
+ border-radius: 20px;
+ background: white;
+ transition: transform 0.3s ease;
+ border: 1px solid #e2e8f0;
+}
+
+.feature-card:hover {
+ transform: translateY(-5px);
+}
+
+.feature-icon {
+ width: 50px;
+ height: 50px;
+ background: rgba(37, 99, 235, 0.1);
+ color: var(--primary-color);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 12px;
+ margin-bottom: 20px;
+ font-size: 1.5rem;
+}
\ No newline at end of file
diff --git a/staticfiles/css/custom.css b/staticfiles/css/custom.css
index 108056f..0ccb83f 100644
--- a/staticfiles/css/custom.css
+++ b/staticfiles/css/custom.css
@@ -1,21 +1,104 @@
-
:root {
- --bg-color-start: #6a11cb;
- --bg-color-end: #2575fc;
- --text-color: #ffffff;
- --card-bg-color: rgba(255, 255, 255, 0.01);
- --card-border-color: rgba(255, 255, 255, 0.1);
+ --primary-color: #2563eb;
+ --secondary-color: #0f172a;
+ --accent-color: #10b981;
+ --bg-light: #f8fafc;
+ --navy: #0f172a;
}
+
body {
- margin: 0;
- font-family: 'Inter', sans-serif;
- background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
- color: var(--text-color);
- display: flex;
- justify-content: center;
- align-items: center;
- min-height: 100vh;
- text-align: center;
- overflow: hidden;
- position: relative;
+ font-family: 'Plus Jakarta Sans', sans-serif;
+ color: #334155;
+ background-color: var(--bg-light);
}
+
+.text-primary { color: var(--primary-color) !important; }
+.btn-primary {
+ background-color: var(--primary-color);
+ border-color: var(--primary-color);
+ font-weight: 600;
+}
+.btn-primary:hover {
+ background-color: #1d4ed8;
+}
+
+.bg-navy { background-color: var(--navy); }
+
+/* Hero Section */
+.hero-section {
+ padding: 100px 0;
+ background: radial-gradient(circle at top right, rgba(37, 99, 235, 0.05), transparent),
+ radial-gradient(circle at bottom left, rgba(16, 185, 129, 0.05), transparent);
+}
+
+.glass-card {
+ background: rgba(255, 255, 255, 0.7);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+ border-radius: 20px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
+}
+
+/* Chat Assistant Widget */
+.chat-container {
+ height: 400px;
+ display: flex;
+ flex-direction: column;
+}
+
+.chat-messages {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding: 15px;
+}
+
+.chat-bubble {
+ padding: 10px 15px;
+ border-radius: 15px;
+ margin-bottom: 10px;
+ max-width: 85%;
+ font-size: 0.9rem;
+}
+
+.bubble-ai {
+ background-color: #f1f5f9;
+ color: #1e293b;
+ align-self: flex-start;
+}
+
+.bubble-user {
+ background-color: var(--primary-color);
+ color: white;
+ align-self: flex-end;
+ margin-left: auto;
+}
+
+.chat-input-area {
+ padding: 15px;
+ border-top: 1px solid #e2e8f0;
+}
+
+.feature-card {
+ padding: 30px;
+ border-radius: 20px;
+ background: white;
+ transition: transform 0.3s ease;
+ border: 1px solid #e2e8f0;
+}
+
+.feature-card:hover {
+ transform: translateY(-5px);
+}
+
+.feature-icon {
+ width: 50px;
+ height: 50px;
+ background: rgba(37, 99, 235, 0.1);
+ color: var(--primary-color);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 12px;
+ margin-bottom: 20px;
+ font-size: 1.5rem;
+}
\ No newline at end of file