diff --git a/polisplexity/settings.py b/polisplexity/settings.py
index 2c5d5e9..043846f 100644
--- a/polisplexity/settings.py
+++ b/polisplexity/settings.py
@@ -15,8 +15,12 @@ sys.path.append(str(BASE_DIR))
# Core security settings
SECRET_KEY = os.getenv("SECRET_KEY")
DEBUG = os.getenv("DEBUG", "False") == "True"
-ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",")
-
+#ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",")
+ALLOWED_HOSTS = [
+ 'localhost',
+ '127.0.0.1',
+ '.ngrok-free.app',
+]
# Application definition
INSTALLED_APPS = [
# Django built-in apps
@@ -60,7 +64,7 @@ INSTALLED_APPS = [
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
CRISPY_TEMPLATE_PACK = "bootstrap5"
-SITE_ID = 2
+SITE_ID = 1
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend", # default
diff --git a/pxy_city_digital_twins/services/osm_city.py b/pxy_city_digital_twins/services/osm_city.py
index a6191c4..0fe8b40 100644
--- a/pxy_city_digital_twins/services/osm_city.py
+++ b/pxy_city_digital_twins/services/osm_city.py
@@ -75,3 +75,46 @@ def generate_osm_city_data(lat, lon, dist=400, scale=1.0):
buildings = []
return {"buildings": buildings}
+
+
+def generate_osm_road_midpoints_only(lat, lon, dist=400, scale=1.0):
+ import osmnx as ox
+ import networkx as nx
+ from shapely.geometry import LineString
+ import geopandas as gpd
+ import random
+
+ print(f"π£οΈ Fetching road midpoints only at ({lat}, {lon})")
+
+ # Obtener grafo y convertir a GeoDataFrame con geometrΓa
+ G = ox.graph_from_point((lat, lon), dist=dist, network_type='drive').to_undirected()
+ edge_gdf = ox.graph_to_gdfs(G, nodes=False, edges=True)
+
+ # Proyectar a metros (3857)
+ edge_gdf = edge_gdf.to_crs(epsg=3857)
+
+ midpoints_raw = []
+ for _, row in edge_gdf.iterrows():
+ geom = row.get('geometry', None)
+ if isinstance(geom, LineString) and geom.length > 0:
+ midpoint = geom.interpolate(0.5, normalized=True)
+ midpoints_raw.append((midpoint.x, midpoint.y))
+
+ if not midpoints_raw:
+ return {"roads": []}
+
+ avg_x = sum(x for x, _ in midpoints_raw) / len(midpoints_raw)
+ avg_z = sum(z for _, z in midpoints_raw) / len(midpoints_raw)
+
+ midpoints = [{
+ "id": f"RD-{i}",
+ "position_x": (x - avg_x) * scale,
+ "position_z": (z - avg_z) * scale,
+ "status": random.choice(["OK", "Warning", "Critical", "Offline"])
+ } for i, (x, z) in enumerate(midpoints_raw)]
+
+ # DEBUG
+ for i in range(min(5, len(midpoints))):
+ print(f"π§ Road {i}: x={midpoints[i]['position_x']:.2f}, z={midpoints[i]['position_z']:.2f}")
+
+ return {"roads": midpoints}
diff --git a/pxy_city_digital_twins/templates/pxy_city_digital_twins/_status_gauge_augmented.html b/pxy_city_digital_twins/templates/pxy_city_digital_twins/_status_gauge_augmented.html
new file mode 100644
index 0000000..e599771
--- /dev/null
+++ b/pxy_city_digital_twins/templates/pxy_city_digital_twins/_status_gauge_augmented.html
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pxy_city_digital_twins/templates/pxy_city_digital_twins/city_augmented_digital_twin.html b/pxy_city_digital_twins/templates/pxy_city_digital_twins/city_augmented_digital_twin.html
new file mode 100644
index 0000000..14547d6
--- /dev/null
+++ b/pxy_city_digital_twins/templates/pxy_city_digital_twins/city_augmented_digital_twin.html
@@ -0,0 +1,65 @@
+{% load static %}
+
+
+
+
+ Digital Twin City - AR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for road in city_data.roads %}
+
+
+ {% include "pxy_city_digital_twins/_status_gauge.html" with ring_color="#FF6600" offset_y="0" status=road.status id=road.id %}
+
+
+ {% endfor %}
+
+
+
+
diff --git a/pxy_city_digital_twins/templates/pxy_city_digital_twins/spawn_gauge_ahead.html b/pxy_city_digital_twins/templates/pxy_city_digital_twins/spawn_gauge_ahead.html
new file mode 100644
index 0000000..6ed5239
--- /dev/null
+++ b/pxy_city_digital_twins/templates/pxy_city_digital_twins/spawn_gauge_ahead.html
@@ -0,0 +1,59 @@
+{% load static %}
+
+
+
+
+ Gauge Ahead
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% include "pxy_city_digital_twins/_status_gauge_augmented.html" with pos_x="0" pos_y="1.6" pos_z="-3" scale="2.7 2.7 2.7" ring_color="#00FF00" label="WELCOME\nUSER" %}
+
+
+
+
+
+
+
diff --git a/pxy_city_digital_twins/urls.py b/pxy_city_digital_twins/urls.py
index 85d593d..a72babe 100644
--- a/pxy_city_digital_twins/urls.py
+++ b/pxy_city_digital_twins/urls.py
@@ -2,10 +2,11 @@ from django.urls import path
from . import views
urlpatterns = [
- # Pattern to accept UUIDs
+ # Digital Twin (normal)
path('city/digital/twin//', views.city_digital_twin, name='city_digital_twin_uuid'),
-
- # Pattern to accept string words
path('city/digital/twin//', views.city_digital_twin, name='city_digital_twin_str'),
-
+
+ # Augmented Digital Twin
+ path('city/augmented/digital/twin//', views.city_augmented_digital_twin, name='city_augmented_digital_twin_uuid'),
+ path('city/augmented/digital/twin//', views.city_augmented_digital_twin, name='city_augmented_digital_twin_str'),
]
diff --git a/pxy_city_digital_twins/views.py b/pxy_city_digital_twins/views.py
index d7cf6b6..25d4979 100644
--- a/pxy_city_digital_twins/views.py
+++ b/pxy_city_digital_twins/views.py
@@ -12,7 +12,7 @@ from .services.layouts import (
)
from .services.random_city import generate_random_city_data
from .services.com_con_city import generate_com_con_city_data
-from .services.osm_city import generate_osm_city_data
+from .services.osm_city import generate_osm_city_data, generate_osm_road_midpoints_only
@@ -135,3 +135,33 @@ def get_example_data():
}
]
}
+
+def city_augmented_digital_twin(request, city_id):
+ try:
+ lat = float(request.GET.get('lat', 0))
+ long = float(request.GET.get('long', 0))
+ scale = float(request.GET.get('scale', 1.0)) # default to 1.0
+
+ if city_id == "osm_city":
+ city_data = generate_osm_road_midpoints_only(lat, long, scale=scale)
+ elif city_id == "random_city":
+ city_data = generate_random_city_data()
+ elif city_id == "gauge_ahead":
+ # No city data needed, just render the special AR scene
+ return render(request, 'pxy_city_digital_twins/spawn_gauge_ahead.html')
+ else:
+ raise Http404("Unsupported city_id for AR view")
+
+ preset = get_environment_preset(lat, long)
+
+ context = {
+ 'city_data': city_data,
+ 'environment_preset': preset,
+ 'lat': lat,
+ 'long': long,
+ }
+ return render(request, 'pxy_city_digital_twins/city_augmented_digital_twin.html', context)
+
+ except (ValueError, TypeError):
+ raise Http404("Invalid parameters provided.")
+
diff --git a/pxy_dashboard/apps/urls.py b/pxy_dashboard/apps/urls.py
index d300cf2..eef1069 100644
--- a/pxy_dashboard/apps/urls.py
+++ b/pxy_dashboard/apps/urls.py
@@ -1,5 +1,6 @@
from django.urls import path
from pxy_dashboard.apps.views import (
+ # Existing
apps_calendar_view,
apps_chat_view,
apps_email_inbox_view,
@@ -8,24 +9,70 @@ from pxy_dashboard.apps.views import (
apps_tasks_details,
apps_kanban_board,
apps_file_manager,
+
+ # New β Waste Collection (Pre-Operation)
+ apps_zone_definition,
+ apps_route_optimization,
+ apps_dispatch_plan,
+
+ # New β Operation
+ apps_urban_digital_twin,
+ apps_whatsapp_bot,
+ apps_telegram_bot,
+ apps_facebook_pages_bot,
+ apps_feedback_loop,
+
+ # New β Post-Operation
+ apps_route_analytics,
+ apps_feedback_review,
+ apps_twin_refinement,
+
+ # New β System Control
+ apps_sync_monitor,
+ apps_logs_webhooks,
+ apps_logs_parsing,
+ apps_logs_limits,
+ apps_config_api,
+ apps_config_map,
+ apps_config_collection,
)
+
app_name = "apps"
-
urlpatterns = [
- # Calaendar
- path("calendar", view=apps_calendar_view, name="calendar"),
- # Chat
- path("chat", view=apps_chat_view, name="chat"),
- # Email
- path("email-inbox", view=apps_email_inbox_view, name="email-inbox"),
- path("email-read", view=apps_email_read, name="email-read"),
- # Tasks
- path("tasks", view=apps_tasks, name="tasks"),
- path("tasks-details", view=apps_tasks_details, name="tasks-details"),
- # Kanban
- path("kanban-board", view=apps_kanban_board, name="kanban"),
- # File Manager
- path("file-manager", view=apps_file_manager, name="file-manager"),
+ # Existing
+ path("calendar", apps_calendar_view, name="calendar"),
+ path("chat", apps_chat_view, name="chat"),
+ path("email-inbox", apps_email_inbox_view, name="email-inbox"),
+ path("email-read", apps_email_read, name="email-read"),
+ path("tasks", apps_tasks, name="tasks"),
+ path("tasks-details", apps_tasks_details, name="tasks-details"),
+ path("kanban-board", apps_kanban_board, name="kanban"),
+ path("file-manager", apps_file_manager, name="file-manager"),
+ # Pre-Operation
+ path("zone-definition", apps_zone_definition, name="zone-definition"),
+ path("route-optimization", apps_route_optimization, name="route-optimization"),
+ path("dispatch-plan", apps_dispatch_plan, name="dispatch-plan"),
+
+ # Operation
+ path("urban-digital-twin", apps_urban_digital_twin, name="urban-digital-twin"),
+ path("bot-whatsapp", apps_whatsapp_bot, name="bot-whatsapp"),
+ path("bot-telegram", apps_telegram_bot, name="bot-telegram"),
+ path("bot-facebook", apps_facebook_pages_bot, name="bot-facebook"),
+ path("feedback-loop", apps_feedback_loop, name="feedback-loop"),
+
+ # Post-Operation
+ path("route-analytics", apps_route_analytics, name="route-analytics"),
+ path("feedback-review", apps_feedback_review, name="feedback-review"),
+ path("twin-refinement", apps_twin_refinement, name="twin-refinement"),
+
+ # System Control
+ path("sync-monitor", apps_sync_monitor, name="sync-monitor"),
+ path("logs-webhooks", apps_logs_webhooks, name="logs-webhooks"),
+ path("logs-parsing", apps_logs_parsing, name="logs-parsing"),
+ path("logs-limits", apps_logs_limits, name="logs-limits"),
+ path("config-api", apps_config_api, name="config-api"),
+ path("config-map", apps_config_map, name="config-map"),
+ path("config-collection", apps_config_collection, name="config-collection"),
]
diff --git a/pxy_dashboard/apps/views.py b/pxy_dashboard/apps/views.py
index a7ca755..6cccef5 100644
--- a/pxy_dashboard/apps/views.py
+++ b/pxy_dashboard/apps/views.py
@@ -5,12 +5,13 @@ from django.contrib.auth.mixins import LoginRequiredMixin
class AppsView(LoginRequiredMixin, TemplateView):
pass
+# βββββ Existing ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# Calendar
apps_calendar_view = AppsView.as_view(template_name="pxy_dashboard/apps/apps-calendar.html")
# Chat
apps_chat_view = AppsView.as_view(template_name="pxy_dashboard/apps/apps-chat.html")
-# Mail Box
+# Email
apps_email_inbox_view = AppsView.as_view(template_name="pxy_dashboard/apps/apps-email-inbox.html")
apps_email_read = AppsView.as_view(template_name="pxy_dashboard/apps/apps-email-read.html")
# Tasks
@@ -20,3 +21,31 @@ apps_tasks_details = AppsView.as_view(template_name="pxy_dashboard/apps/apps-tas
apps_kanban_board = AppsView.as_view(template_name="pxy_dashboard/apps/apps-kanban.html")
# File Manager
apps_file_manager = AppsView.as_view(template_name="pxy_dashboard/apps/apps-file-manager.html")
+
+# βββββ Waste Collection Intelligence βββββββββββββββββββββββββββββββββββββββββ
+
+# Pre-Operation
+apps_zone_definition = AppsView.as_view(template_name="pxy_dashboard/apps/apps-zone-definition.html")
+apps_route_optimization = AppsView.as_view(template_name="pxy_dashboard/apps/apps-route-optimization.html")
+apps_dispatch_plan = AppsView.as_view(template_name="pxy_dashboard/apps/apps-dispatch-plan.html")
+
+# Operation β Physical & Social Digital Twin
+apps_urban_digital_twin = AppsView.as_view(template_name="pxy_dashboard/apps/apps-urban-digital-twin.html")
+apps_whatsapp_bot = AppsView.as_view(template_name="pxy_dashboard/apps/apps-whatsapp-bot.html")
+apps_telegram_bot = AppsView.as_view(template_name="pxy_dashboard/apps/apps-telegram-bot.html")
+apps_facebook_pages_bot = AppsView.as_view(template_name="pxy_dashboard/apps/apps-facebook-pages-bot.html")
+apps_feedback_loop = AppsView.as_view(template_name="pxy_dashboard/apps/apps-feedback-loop.html")
+
+# Post-Operation
+apps_route_analytics = AppsView.as_view(template_name="pxy_dashboard/apps/apps-route-analytics.html")
+apps_feedback_review = AppsView.as_view(template_name="pxy_dashboard/apps/apps-feedback-review.html")
+apps_twin_refinement = AppsView.as_view(template_name="pxy_dashboard/apps/apps-twin-refinement.html")
+
+# System Control
+apps_sync_monitor = AppsView.as_view(template_name="pxy_dashboard/apps/apps-sync-monitor.html")
+apps_logs_webhooks = AppsView.as_view(template_name="pxy_dashboard/apps/apps-logs-webhooks.html")
+apps_logs_parsing = AppsView.as_view(template_name="pxy_dashboard/apps/apps-logs-parsing.html")
+apps_logs_limits = AppsView.as_view(template_name="pxy_dashboard/apps/apps-logs-limits.html")
+apps_config_api = AppsView.as_view(template_name="pxy_dashboard/apps/apps-config-api.html")
+apps_config_map = AppsView.as_view(template_name="pxy_dashboard/apps/apps-config-map.html")
+apps_config_collection = AppsView.as_view(template_name="pxy_dashboard/apps/apps-config-collection.html")
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-api.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-api.html
new file mode 100644
index 0000000..92f5da8
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-api.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Config Api
+This is a placeholder page for apps-config-api.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-collection.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-collection.html
new file mode 100644
index 0000000..9a680fd
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-collection.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Config Collection
+This is a placeholder page for apps-config-collection.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-map.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-map.html
new file mode 100644
index 0000000..106ee73
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-config-map.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Config Map
+This is a placeholder page for apps-config-map.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-dispatch-plan.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-dispatch-plan.html
new file mode 100644
index 0000000..89485e2
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-dispatch-plan.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Dispatch Plan
+This is a placeholder page for apps-dispatch-plan.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-facebook-pages-bot.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-facebook-pages-bot.html
new file mode 100644
index 0000000..e599fda
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-facebook-pages-bot.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Facebook Pages Bot
+This is a placeholder page for apps-facebook-pages-bot.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-loop.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-loop.html
new file mode 100644
index 0000000..137da7d
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-loop.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Feedback Loop
+This is a placeholder page for apps-feedback-loop.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-review.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-review.html
new file mode 100644
index 0000000..2abf78f
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-feedback-review.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Feedback Review
+This is a placeholder page for apps-feedback-review.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-limits.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-limits.html
new file mode 100644
index 0000000..eddd753
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-limits.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Logs Limits
+This is a placeholder page for apps-logs-limits.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-parsing.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-parsing.html
new file mode 100644
index 0000000..99a7912
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-parsing.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Logs Parsing
+This is a placeholder page for apps-logs-parsing.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-webhooks.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-webhooks.html
new file mode 100644
index 0000000..93e5b56
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-logs-webhooks.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Logs Webhooks
+This is a placeholder page for apps-logs-webhooks.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-analytics.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-analytics.html
new file mode 100644
index 0000000..30396c3
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-analytics.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Route Analytics
+This is a placeholder page for apps-route-analytics.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-optimization.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-optimization.html
new file mode 100644
index 0000000..7d0227d
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-route-optimization.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Route Optimization
+This is a placeholder page for apps-route-optimization.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-sync-monitor.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-sync-monitor.html
new file mode 100644
index 0000000..876559a
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-sync-monitor.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Sync Monitor
+This is a placeholder page for apps-sync-monitor.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-telegram-bot.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-telegram-bot.html
new file mode 100644
index 0000000..58db716
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-telegram-bot.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Telegram Bot
+This is a placeholder page for apps-telegram-bot.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-twin-refinement.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-twin-refinement.html
new file mode 100644
index 0000000..31da21d
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-twin-refinement.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Twin Refinement
+This is a placeholder page for apps-twin-refinement.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-urban-digital-twin.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-urban-digital-twin.html
new file mode 100644
index 0000000..3d8d528
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-urban-digital-twin.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Urban Digital Twin
+This is a placeholder page for apps-urban-digital-twin.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-whatsapp-bot.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-whatsapp-bot.html
new file mode 100644
index 0000000..0c0c871
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-whatsapp-bot.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Whatsapp Bot
+This is a placeholder page for apps-whatsapp-bot.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/apps/apps-zone-definition.html b/pxy_dashboard/templates/pxy_dashboard/apps/apps-zone-definition.html
new file mode 100644
index 0000000..4fbafec
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/apps/apps-zone-definition.html
@@ -0,0 +1,5 @@
+{% extends "pxy_dashboard/partials/base.html" %}
+{% block content %}
+Zone Definition
+This is a placeholder page for apps-zone-definition.html
+{% endblock %}
diff --git a/pxy_dashboard/templates/pxy_dashboard/partials/__left-sidebar.html b/pxy_dashboard/templates/pxy_dashboard/partials/__left-sidebar.html
new file mode 100644
index 0000000..b4bd3b0
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/partials/__left-sidebar.html
@@ -0,0 +1,666 @@
+{% load static %}
+
+
+
\ No newline at end of file
diff --git a/pxy_dashboard/templates/pxy_dashboard/partials/__right-sidebar.html b/pxy_dashboard/templates/pxy_dashboard/partials/__right-sidebar.html
new file mode 100644
index 0000000..607083f
--- /dev/null
+++ b/pxy_dashboard/templates/pxy_dashboard/partials/__right-sidebar.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+ Customize the overall color scheme, sidebar menu, etc.
+
+
+
Choose Layout
+
+
+
Color Scheme
+
+
+
+
+
+
Topbar Color
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pxy_dashboard/templates/pxy_dashboard/partials/left-sidebar.html b/pxy_dashboard/templates/pxy_dashboard/partials/left-sidebar.html
index b4bd3b0..96fb6fc 100644
--- a/pxy_dashboard/templates/pxy_dashboard/partials/left-sidebar.html
+++ b/pxy_dashboard/templates/pxy_dashboard/partials/left-sidebar.html
@@ -50,615 +50,14 @@
+
+
{% load sidebar_menu %}
{% render_sidebar_menu sidebar_menu %}
-
-
-
+
diff --git a/pxy_dashboard/templates/pxy_dashboard/partials/sidebar_menu_node.html b/pxy_dashboard/templates/pxy_dashboard/partials/sidebar_menu_node.html
index 6cf9983..431569f 100644
--- a/pxy_dashboard/templates/pxy_dashboard/partials/sidebar_menu_node.html
+++ b/pxy_dashboard/templates/pxy_dashboard/partials/sidebar_menu_node.html
@@ -4,8 +4,8 @@
{% elif item.children %}
-
-
+
+
{{ item.label }}
@@ -17,7 +17,8 @@
{% else %}
- {{ child.label }}
+
+ {{ child.label }}
{% endif %}
@@ -26,15 +27,15 @@
-{% else %}
-
-
-
- {% if item.badge %}
- {{ item.badge }}
- {% endif %}
- {{ item.label }}
-
-
-{% endif %}
+ {% else %}
+
+
+
+ {% if item.badge %}
+ {{ item.badge }}
+ {% endif %}
+ {{ item.label }}
+
+
+ {% endif %}
{% endfor %}
diff --git a/sidebar_menu.json b/sidebar_menu.json
index bf5cd9c..92086ad 100644
--- a/sidebar_menu.json
+++ b/sidebar_menu.json
@@ -1,17 +1,201 @@
[
{
- "type": "group",
- "label": "Layouts",
- "icon": "ri-layout-3-fill",
- "order": 140,
+ "type": "title",
+ "label": "Waste Collection Intelligence",
+ "order": 1
+ },
+ {
+ "type": "submenu",
+ "label": "Pre-Operation",
+ "icon": "ri-settings-3-fill",
+ "order": 2,
"children": [
- { "type": "link", "label": "Horizontal", "url": "layouts:horizontal", "order": 10 },
- { "type": "link", "label": "Detached", "url": "layouts:detached", "order": 20 },
- { "type": "link", "label": "Full View", "url": "layouts:full", "order": 30 },
- { "type": "link", "label": "Fullscreen View", "url": "layouts:fullscreen", "order": 40 },
- { "type": "link", "label": "Hover Menu", "url": "layouts:hover", "order": 50 },
- { "type": "link", "label": "Compact", "url": "layouts:compact", "order": 60 },
- { "type": "link", "label": "Icon View", "url": "layouts:icon-view", "order": 70 }
+ {
+ "type": "link",
+ "label": "Zone Definition & Depot Upload",
+ "url": "apps:zone-definition",
+ "icon": "ri-map-pin-2-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Route Optimization",
+ "url": "apps:route-optimization",
+ "icon": "ri-shuffle-fill",
+ "order": 2
+ },
+ {
+ "type": "link",
+ "label": "Download Dispatch Plan",
+ "url": "apps:dispatch-plan",
+ "icon": "ri-download-2-fill",
+ "order": 3
+ }
+ ]
+ },
+ {
+ "type": "submenu",
+ "label": "Operation",
+ "icon": "ri-road-map-fill",
+ "order": 3,
+ "children": [
+ {
+ "type": "link",
+ "label": "Urban Digital Twin",
+ "url": "apps:urban-digital-twin",
+ "icon": "ri-building-2-fill",
+ "order": 1
+ },
+ {
+ "type": "submenu",
+ "label": "Social Digital Twin",
+ "icon": "ri-group-fill",
+ "order": 2,
+ "children": [
+ {
+ "type": "link",
+ "label": "WhatsApp Bot",
+ "url": "apps:bot-whatsapp",
+ "icon": "ri-whatsapp-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Telegram Bot",
+ "url": "apps:bot-telegram",
+ "icon": "ri-telegram-fill",
+ "order": 2
+ },
+ {
+ "type": "link",
+ "label": "Facebook Pages Bot",
+ "url": "apps:bot-facebook",
+ "icon": "ri-facebook-fill",
+ "order": 3
+ }
+ ]
+ },
+ {
+ "type": "link",
+ "label": "Data Feedback Loop",
+ "url": "apps:feedback-loop",
+ "icon": "ri-loop-left-line",
+ "order": 3
+ }
+ ]
+ },
+ {
+ "type": "submenu",
+ "label": "Post-Operation",
+ "icon": "ri-bar-chart-box-fill",
+ "order": 4,
+ "children": [
+ {
+ "type": "link",
+ "label": "Route Analytics",
+ "url": "apps:route-analytics",
+ "icon": "ri-line-chart-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Citizen Feedback Review",
+ "url": "apps:feedback-review",
+ "icon": "ri-message-3-fill",
+ "order": 2
+ },
+ {
+ "type": "link",
+ "label": "Twin Refinement",
+ "url": "apps:twin-refinement",
+ "icon": "ri-slideshow-2-fill",
+ "order": 3
+ }
+ ]
+ },
+ {
+ "type": "title",
+ "label": "System Control",
+ "order": 5
+ },
+ {
+ "type": "submenu",
+ "label": "Digital Twin Sync Monitor",
+ "icon": "ri-refresh-fill",
+ "order": 6,
+ "children": [
+ {
+ "type": "link",
+ "label": "Sync Status",
+ "url": "apps:sync-monitor",
+ "icon": "ri-check-double-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Force Refresh",
+ "url": "apps:sync-monitor",
+ "icon": "ri-restart-fill",
+ "order": 2
+ }
+ ]
+ },
+ {
+ "type": "submenu",
+ "label": "Logs & Failures",
+ "icon": "ri-error-warning-fill",
+ "order": 7,
+ "children": [
+ {
+ "type": "link",
+ "label": "Webhook Logs",
+ "url": "apps:logs-webhooks",
+ "icon": "ri-file-list-2-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Parsing Errors",
+ "url": "apps:logs-parsing",
+ "icon": "ri-bug-fill",
+ "order": 2
+ },
+ {
+ "type": "link",
+ "label": "API Limits",
+ "url": "apps:logs-limits",
+ "icon": "ri-cpu-fill",
+ "order": 3
+ }
+ ]
+ },
+ {
+ "type": "submenu",
+ "label": "Configuration",
+ "icon": "ri-settings-5-fill",
+ "order": 8,
+ "children": [
+ {
+ "type": "link",
+ "label": "API Keys & Tokens",
+ "url": "apps:config-api",
+ "icon": "ri-key-2-fill",
+ "order": 1
+ },
+ {
+ "type": "link",
+ "label": "Map Rendering",
+ "url": "apps:config-map",
+ "icon": "ri-map-pin-user-fill",
+ "order": 2
+ },
+ {
+ "type": "link",
+ "label": "Collection Logic",
+ "url": "apps:config-collection",
+ "icon": "ri-truck-fill",
+ "order": 3
+ }
]
}
]