1/2/26 V.3
This commit is contained in:
parent
31218d3fe4
commit
fa77b3759c
BIN
ai/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
ai/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ai/__pycache__/local_ai_api.cpython-311.pyc
Normal file
BIN
ai/__pycache__/local_ai_api.cpython-311.pyc
Normal file
Binary file not shown.
BIN
assets/pasted-20260103-014310-373c563f.png
Normal file
BIN
assets/pasted-20260103-014310-373c563f.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
assets/pasted-20260103-020327-3917de79.png
Normal file
BIN
assets/pasted-20260103-020327-3917de79.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -60,6 +60,30 @@
|
|||||||
👥 Teams
|
👥 Teams
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
<p class="px-6 mt-4 text-xs text-gray-500 uppercase tracking-wider">Daily Operations</p>
|
||||||
|
<nav class="px-4 py-2 space-y-1">
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
📝 Daily Logs
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
🛡️ Safety Meetings
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
🚨 Incidents
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<p class="px-6 mt-4 text-xs text-gray-500 uppercase tracking-wider">Compliance</p>
|
||||||
|
<nav class="px-4 py-2 space-y-1">
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
📄 Documents
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
👷 Subcontractors
|
||||||
|
</a>
|
||||||
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
|
🔧 Equipment
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
<p class="px-6 mt-4 text-xs text-gray-500 uppercase tracking-wider">Projects</p>
|
<p class="px-6 mt-4 text-xs text-gray-500 uppercase tracking-wider">Projects</p>
|
||||||
<nav class="px-4 py-2 space-y-1">
|
<nav class="px-4 py-2 space-y-1">
|
||||||
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
@ -82,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="border-t border-gray-200">
|
<div class="border-t border-gray-200">
|
||||||
<nav class="px-4 py-4 space-y-1">
|
<nav class="px-4 py-4 space-y-1">
|
||||||
<a href="/admin" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
<a href="{% url 'settings' %}" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
⚙️ Settings
|
⚙️ Settings
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
<a href="#" class="flex items-center px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200 rounded-lg">
|
||||||
@ -98,12 +122,13 @@
|
|||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h1 class="text-2xl font-semibold text-gray-800">ComplianceShield Dashboard</h1>
|
<h1 class="text-2xl font-semibold text-gray-800">ComplianceShield Dashboard</h1>
|
||||||
<div class="flex-1 flex justify-center px-8">
|
<div class="flex-1 flex justify-center px-8">
|
||||||
<div class="relative w-full max-w-lg">
|
<form action="/search" method="post" class="relative w-full max-w-lg">
|
||||||
|
{% csrf_token %}
|
||||||
<span class="absolute inset-y-0 left-0 flex items-center pl-3">
|
<span class="absolute inset-y-0 left-0 flex items-center pl-3">
|
||||||
<i-o-magnifying-glass class="h-5 w-5 text-gray-500"></i-o-magnifying-glass>
|
<i-o-magnifying-glass class="h-5 w-5 text-gray-500"></i-o-magnifying-glass>
|
||||||
</span>
|
</span>
|
||||||
<input type="text" placeholder="Search..." class="block w-full rounded-md border border-gray-200 bg-gray-50 py-2 pl-10 pr-4 text-gray-900 placeholder-gray-500 focus:ring-2 focus:ring-inset focus:ring-blue-500 sm:text-sm">
|
<input type="text" name="query" placeholder="Search..." class="search-bar block w-full rounded-md border border-gray-200 bg-gray-50 py-2 pl-10 pr-4 text-gray-900 placeholder-gray-500 focus:ring-2 focus:ring-inset focus:ring-blue-500 sm:text-sm">
|
||||||
</div>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<i-o-bell class="h-6 w-6 text-gray-500"></i-o-bell>
|
<i-o-bell class="h-6 w-6 text-gray-500"></i-o-bell>
|
||||||
@ -117,6 +142,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="search-results" class="mt-6">
|
||||||
|
{% if search_results %}
|
||||||
|
<div class="panel p-6">
|
||||||
|
<h3 class="font-semibold">Search Results</h3>
|
||||||
|
<p class="text-sm text-gray-500">{{ search_results }}</p>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="panel p-6 mb-8">
|
<div class="panel p-6 mb-8">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
11
core/templates/core/settings.html
Normal file
11
core/templates/core/settings.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}Settings{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="p-6 lg:p-10">
|
||||||
|
<h1 class="text-2xl font-semibold text-gray-800">Settings</h1>
|
||||||
|
<p class="text-gray-600">This is the settings page.</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from .views import index
|
from .views import index, search, settings
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", index, name="index"),
|
path("", index, name="index"),
|
||||||
|
path("search", search, name="search"),
|
||||||
|
path("settings", settings, name="settings"),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,8 +1,49 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render, redirect
|
||||||
|
from ai.local_ai_api import LocalAIApi
|
||||||
|
import json
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
context = {
|
context = {
|
||||||
"project_name": "ComplianceShield",
|
"project_name": "ComplianceShield",
|
||||||
}
|
}
|
||||||
return render(request, "core/index.html", context)
|
return render(request, "core/index.html", context)
|
||||||
|
|
||||||
|
def search(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
query = request.POST.get("query", "")
|
||||||
|
if query:
|
||||||
|
response = LocalAIApi.create_response(
|
||||||
|
{
|
||||||
|
"input": [
|
||||||
|
{"role": "system", "content": "You are a helpful assistant."},
|
||||||
|
{"role": "user", "content": query},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"poll_interval": 5, # seconds
|
||||||
|
"poll_timeout": 300, # seconds
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if response.get("success"):
|
||||||
|
text = LocalAIApi.extract_text(response)
|
||||||
|
if not text:
|
||||||
|
decoded = LocalAIApi.decode_json_from_response(response)
|
||||||
|
text = json.dumps(decoded, ensure_ascii=False) if decoded else str(response.get("data", ""))
|
||||||
|
search_results = text
|
||||||
|
else:
|
||||||
|
search_results = "Error: Could not get a response from the AI."
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"project_name": "ComplianceShield",
|
||||||
|
"search_results": search_results,
|
||||||
|
}
|
||||||
|
return render(request, "core/index.html", context)
|
||||||
|
|
||||||
|
return redirect("index")
|
||||||
|
|
||||||
|
def settings(request):
|
||||||
|
context = {
|
||||||
|
"project_name": "ComplianceShield",
|
||||||
|
}
|
||||||
|
return render(request, "core/settings.html", context)
|
||||||
|
|||||||
@ -51,4 +51,8 @@
|
|||||||
}
|
}
|
||||||
.btn:hover { transform: translateY(-1px); box-shadow: 0 18px 48px rgba(11,11,12,.10); }
|
.btn:hover { transform: translateY(-1px); box-shadow: 0 18px 48px rgba(11,11,12,.10); }
|
||||||
|
|
||||||
.drawer.hidden { display:none; }
|
.drawer.hidden { display:none; }
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
}
|
||||||
@ -51,4 +51,8 @@
|
|||||||
}
|
}
|
||||||
.btn:hover { transform: translateY(-1px); box-shadow: 0 18px 48px rgba(11,11,12,.10); }
|
.btn:hover { transform: translateY(-1px); box-shadow: 0 18px 48px rgba(11,11,12,.10); }
|
||||||
|
|
||||||
.drawer.hidden { display:none; }
|
.drawer.hidden { display:none; }
|
||||||
|
|
||||||
|
.search-bar {
|
||||||
|
border: 1px solid #000 !important;
|
||||||
|
}
|
||||||
BIN
staticfiles/pasted-20260102-044444-abfd6e7e.png
Normal file
BIN
staticfiles/pasted-20260102-044444-abfd6e7e.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
staticfiles/pasted-20260103-013028-c48a4f62.png
Normal file
BIN
staticfiles/pasted-20260103-013028-c48a4f62.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
staticfiles/pasted-20260103-014310-373c563f.png
Normal file
BIN
staticfiles/pasted-20260103-014310-373c563f.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
staticfiles/pasted-20260103-020327-3917de79.png
Normal file
BIN
staticfiles/pasted-20260103-020327-3917de79.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Loading…
x
Reference in New Issue
Block a user