Lots of changes...
This commit is contained in:
parent
f138fb7b44
commit
6ad41ecae2
18 changed files with 257 additions and 168 deletions
|
@ -22,8 +22,8 @@ SECRET_KEY = ASK.secret_key
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = [ASK.config["ACADEMON"]["Host"]]
|
||||||
|
CSRF_TRUSTED_ORIGINS = [f"https://{host}" for host in ALLOWED_HOSTS]
|
||||||
|
|
||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
|
@ -128,12 +128,22 @@ USE_TZ = True
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = '/static/'
|
||||||
|
|
||||||
|
STATIC_ROOT = None if DEBUG else ASK.config.get("ACADEMON", "StaticRoot", fallback=BASE_DIR / "static")
|
||||||
|
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
BASE_DIR / "static",
|
BASE_DIR / "static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if "S3" in ASK.config:
|
||||||
|
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||||
|
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'
|
||||||
|
AWS_ACCESS_KEY_ID = ASK.config.get("S3", "AccessKey")
|
||||||
|
AWS_SECRET_ACCESS_KEY = ASK.config.get("S3", "SecretKey")
|
||||||
|
AWS_STORAGE_BUCKET_NAME = ASK.config.get("S3", "Bucket")
|
||||||
|
AWS_S3_ENDPOINT_URL = ASK.config.get("S3", "Endpoint")
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,6 @@ from django.urls import path, include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('api/', include(("api.urls", "api"))),
|
||||||
path('', include(("core.urls", "core"))),
|
path('', include(("core.urls", "core"))),
|
||||||
]
|
]
|
||||||
|
|
0
api/__init__.py
Normal file
0
api/__init__.py
Normal file
3
api/admin.py
Normal file
3
api/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
6
api/apps.py
Normal file
6
api/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class ApiConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'api'
|
0
api/migrations/__init__.py
Normal file
0
api/migrations/__init__.py
Normal file
3
api/models.py
Normal file
3
api/models.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
3
api/tests.py
Normal file
3
api/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
4
api/urls.py
Normal file
4
api/urls.py
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
from django.urls import path, include
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
]
|
3
api/views.py
Normal file
3
api/views.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
# Create your views here.
|
|
@ -3,19 +3,23 @@ from django.contrib.auth import get_user_model
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
from reportmonster.classes.vessel import Vessel
|
||||||
|
|
||||||
from bcrypt import checkpw
|
from bcrypt import checkpw
|
||||||
|
|
||||||
|
|
||||||
class ReportMonsterBackend(ModelBackend):
|
class ReportMonsterBackend(ModelBackend):
|
||||||
def authenticate(self, request, username: str = None, password:str = None):
|
def authenticate(self, request, username: str = None, password: str = None):
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
monster = settings.MONSTERCONFIG
|
monster = settings.MONSTERCONFIG
|
||||||
loginvessel = filter(lambda x: x.name = settings.LOGIN_VESSEL, monster.vessels)[0]
|
loginvessel = list(
|
||||||
|
filter(lambda x: x.name == settings.LOGIN_VESSEL, monster.vessels)
|
||||||
|
)[0]
|
||||||
|
|
||||||
|
userdata = list(loginvessel.getUsers(username=username).values())[0]
|
||||||
|
|
||||||
if checkpw(password.encode(), userdata.content["password"].encode()):
|
if checkpw(password.encode(), userdata["password"].encode()):
|
||||||
user, _ = get_user_model().objects.get_or_create(email=username)
|
user, _ = get_user_model().objects.get_or_create(email=username)
|
||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
|
33
core/models/vessel.py
Normal file
33
core/models/vessel.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from pycruisemapper.classes import CruiseMapper, Ship
|
||||||
|
|
||||||
|
|
||||||
|
class Vessel(models.Model):
|
||||||
|
name = models.CharField(max_length=64)
|
||||||
|
imo = models.IntegerField(null=True, blank=True)
|
||||||
|
mmsi = models.IntegerField(null=True, blank=True)
|
||||||
|
|
||||||
|
def query_cruisemapper(self) -> Ship:
|
||||||
|
cm = CruiseMapper()
|
||||||
|
all_ships = cm.get_ships()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.imo:
|
||||||
|
filtered = filter(lambda x: x.imo == self.imo, all_ships)
|
||||||
|
elif self.mmsi:
|
||||||
|
filtered = filter(lambda x: x.mmsi == self.mmsi, all_ships)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
ship = list(filtered)[0]
|
||||||
|
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
ship = cm.fill_ship(ship)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return ship
|
|
@ -1,10 +1,12 @@
|
||||||
from django.urls import path, reverse_lazy
|
from django.urls import path, reverse_lazy
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
|
|
||||||
from ..views.frontend import DashboardView
|
from ..views.frontend import DashboardView, NotImplementedView
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
path("admin/", NotImplementedView.as_view(), name="admin"),
|
||||||
|
path("admin/vessels/", NotImplementedView.as_view(), name="admin_vessels"),
|
||||||
path("dashboard/", DashboardView.as_view(), name="dashboard"),
|
path("dashboard/", DashboardView.as_view(), name="dashboard"),
|
||||||
path("", RedirectView.as_view(url=reverse_lazy("core:dashboard"))),
|
path("", RedirectView.as_view(url=reverse_lazy("core:dashboard"))),
|
||||||
]
|
]
|
7
core/views/admin.py
Normal file
7
core/views/admin.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django.views.generic import ListView
|
||||||
|
|
||||||
|
from ..mixins.auth import SuperuserRequiredMixin
|
||||||
|
|
||||||
|
|
||||||
|
class AdminVesselsListView(TemplateView, SuperuserRequiredMixin):
|
||||||
|
template_name = "core/base.html"
|
|
@ -1,8 +1,14 @@
|
||||||
django
|
django
|
||||||
dbsettings
|
|
||||||
django-autosecretkey
|
|
||||||
pyotp
|
pyotp
|
||||||
bcrypt
|
bcrypt
|
||||||
|
certifi
|
||||||
|
django-storages
|
||||||
|
boto3
|
||||||
|
django-ajax-datatable
|
||||||
|
|
||||||
|
dbsettings
|
||||||
|
django-autosecretkey
|
||||||
|
pycruisemapper
|
||||||
|
|
||||||
git+https://kumig.it/kumisystems/reportmonster.git
|
git+https://kumig.it/kumisystems/reportmonster.git
|
||||||
git+https://kumig.it/kumisystems/pyadonis.git
|
git+https://kumig.it/kumisystems/pyadonis.git
|
|
@ -1,20 +1,26 @@
|
||||||
[ACADEMON]
|
[ACADEMON]
|
||||||
|
Host = academon.example.com
|
||||||
|
|
||||||
|
[ADONIS]
|
||||||
|
CrewPortalBaseURL=http://adonis/AdonisWebServices/CrewPortalWebService.svc/
|
||||||
|
Login=Adonis_API
|
||||||
|
Password=
|
||||||
|
|
||||||
[REPORTMONSTER]
|
[REPORTMONSTER]
|
||||||
Login = 1
|
Login = 1
|
||||||
LoginVessel = test
|
LoginVessel = Login
|
||||||
|
|
||||||
[Vessel test]
|
# Define a ReportMonster vessel to use for authentication *only*
|
||||||
|
# To manage that vessel from within AcadeMon set it up in the adimnistration too!
|
||||||
|
# Make sure the vessel name matches LoginVessel in [REPORTMONSTER] above
|
||||||
|
|
||||||
|
[Vessel Login]
|
||||||
Host = 10.11.12.13
|
Host = 10.11.12.13
|
||||||
Username = moodle_test
|
Username = moodle_test
|
||||||
Password = 1quite_secret*indeed!
|
Password = 1quite_secret*indeed!
|
||||||
Database = moodle_test
|
Database = moodle_test
|
||||||
SSH = 1 # Whether or not to tunnel the MySQL connection through SSH
|
SSH = 1 # Whether or not to tunnel the MySQL connection through SSH
|
||||||
# ReportMonster / AcadeMon does not handle authentication, so use SSH agent!
|
# ReportMonster / AcadeMon does not handle SSH auth, so use SSH agent!
|
||||||
|
|
||||||
# Only used if anything actually enables the ReportMonster API
|
|
||||||
# [User test]
|
|
||||||
# Password = test123!
|
|
||||||
|
|
||||||
# [MySQL]
|
# [MySQL]
|
||||||
# Database = academon
|
# Database = academon
|
||||||
|
|
|
@ -4,14 +4,15 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Academon | {{ title }}</title>
|
<title>AcadeMon | {{ title }}</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fontproxy.kumi.systems/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
|
<link rel="stylesheet" href="https://fontproxy.kumi.systems/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{% static "core/dist/css/all.min.css" %}">
|
<link rel="stylesheet" href="{% static "core/dist/css/all.min.css" %}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{% static "core/dist/css/adminlte.min.css" %}?v=3.2.0">
|
<link rel="stylesheet" href="{% static "core/dist/css/adminlte.min.css" %}?v=3.2.0">
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<body class="hold-transition sidebar-mini">
|
<body class="hold-transition sidebar-mini">
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|
||||||
|
@ -61,148 +62,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
{% include "core/frontend/sidebar.html" %}
|
||||||
<aside class="main-sidebar sidebar-dark-primary elevation-4">
|
|
||||||
|
|
||||||
<a href="/" class="brand-link">
|
|
||||||
<img src="{% static "core/dist/img/logo.png" %}" alt="AcadeMon Logo" class="brand-image img-circle elevation-3" style="opacity: .8">
|
|
||||||
<span class="brand-text font-weight-light">Academon</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="sidebar">
|
|
||||||
|
|
||||||
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
|
|
||||||
<div class="image">
|
|
||||||
<img src="{% static "core/dist/img/noavatar.jpg" %}" class="img-circle elevation-2" alt="User Image">
|
|
||||||
</div>
|
|
||||||
<div class="info">
|
|
||||||
<a href="#" class="d-block">{{ user.get_username }}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-inline">
|
|
||||||
<div class="input-group" data-widget="sidebar-search">
|
|
||||||
<input class="form-control form-control-sidebar" type="search" placeholder="Search" aria-label="Search">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-sidebar">
|
|
||||||
<i class="fas fa-search fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<nav class="mt-2">
|
|
||||||
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="{% url "core:dashboard" %}" class="nav-link">
|
|
||||||
<i class="fas fa-tachometer-alt nav-icon"></i>
|
|
||||||
<p>
|
|
||||||
Dashboard
|
|
||||||
<!--<span class="right badge badge-danger">New</span>-->
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<!--<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-copy"></i>
|
|
||||||
<p>
|
|
||||||
Layout Options
|
|
||||||
<i class="fas fa-angle-left right"></i>
|
|
||||||
<span class="badge badge-info right">6</span>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
<ul class="nav nav-treeview">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="pages/layout/top-nav.html" class="nav-link">
|
|
||||||
<i class="far fa-circle nav-icon"></i>
|
|
||||||
<p>Top Navigation</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>-->
|
|
||||||
|
|
||||||
<li class="nav-header">INFRASTRUCTURE</li>
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-ship"></i>
|
|
||||||
<p>
|
|
||||||
Vessel Monitoring <span class="badge badge-danger right">1</span><span class="badge badge-success right">0</span>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-file-export"></i>
|
|
||||||
<p>
|
|
||||||
Backups
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-gears"></i>
|
|
||||||
<p>
|
|
||||||
Services <span class="badge badge-danger right">0</span><span class="badge badge-success right">4</span>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-chart-line"></i>
|
|
||||||
<p>
|
|
||||||
Reports
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
|
|
||||||
<li class="nav-header">CREW</li>
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-users"></i>
|
|
||||||
<p>
|
|
||||||
User Statistics
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-id-card-clip"></i>
|
|
||||||
<p>
|
|
||||||
User Details
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-graduation-cap"></i>
|
|
||||||
<p>
|
|
||||||
Certificates
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li class="nav-header">CONTENTMONSTER</li>
|
|
||||||
|
|
||||||
<li class="nav-item">
|
|
||||||
<a href="#" class="nav-link">
|
|
||||||
<i class="nav-icon fas fa-upload"></i>
|
|
||||||
<p>
|
|
||||||
Current Queue
|
|
||||||
<span class="badge badge-info right">2</span>
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
|
|
||||||
|
@ -242,16 +102,13 @@ All rights reserved.
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script src="{% static "core/dist/js/jquery.min.js" %}"></script>
|
<script src="{% static "core/dist/js/jquery.min.js" %}"></script>
|
||||||
|
|
||||||
<script src="{% static "core/dist/js/bootstrap.bundle.min.js" %}"></script>
|
<script src="{% static "core/dist/js/bootstrap.bundle.min.js" %}"></script>
|
||||||
|
|
||||||
<script src="{% static "core/dist/js/adminlte.js" %}?v=3.2.0"></script>
|
<script src="{% static "core/dist/js/adminlte.js" %}?v=3.2.0"></script>
|
||||||
|
|
||||||
<script src="{% static "core/dist/js/Chart.min.js" %}"></script>
|
<script src="{% static "core/dist/js/Chart.min.js" %}"></script>
|
||||||
|
|
||||||
<script src="{% static "core/dist/js/dashboard3.js" %}"></script>
|
<script src="{% static "core/dist/js/dashboard3.js" %}"></script>
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
141
templates/core/frontend/sidebar.html
Normal file
141
templates/core/frontend/sidebar.html
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<aside class="main-sidebar sidebar-dark-primary elevation-4">
|
||||||
|
|
||||||
|
<a href="/" class="brand-link">
|
||||||
|
<img src="{% static "core/dist/img/logo.png" %}" alt="AcadeMon Logo" class="brand-image img-circle elevation-3"
|
||||||
|
style="opacity: .8">
|
||||||
|
<span class="brand-text font-weight-light">Academon</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="sidebar">
|
||||||
|
|
||||||
|
<div class="user-panel mt-3 pb-3 mb-3 d-flex">
|
||||||
|
<div class="image">
|
||||||
|
<img src="{% static "core/dist/img/noavatar.jpg" %}" class="img-circle elevation-2" alt="User Image">
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<a href="#" class="d-block">{{ user.get_username }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-inline">
|
||||||
|
<div class="input-group" data-widget="sidebar-search">
|
||||||
|
<input class="form-control form-control-sidebar" type="search" placeholder="Search" aria-label="Search">
|
||||||
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-sidebar">
|
||||||
|
<i class="fas fa-search fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="mt-2">
|
||||||
|
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="{% url "core:dashboard" %}" class="nav-link">
|
||||||
|
<i class="fas fa-tachometer-alt nav-icon"></i>
|
||||||
|
<p>
|
||||||
|
Dashboard
|
||||||
|
<!--<span class="right badge badge-danger">New</span>-->
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-header">INFRASTRUCTURE</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-ship"></i>
|
||||||
|
<p>
|
||||||
|
Vessel Monitoring <span class="badge badge-danger right">1</span><span
|
||||||
|
class="badge badge-success right">0</span>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-file-export"></i>
|
||||||
|
<p>
|
||||||
|
Backups
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-gears"></i>
|
||||||
|
<p>
|
||||||
|
Services <span class="badge badge-danger right">0</span><span
|
||||||
|
class="badge badge-success right">4</span>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-chart-line"></i>
|
||||||
|
<p>
|
||||||
|
Reports
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li class="nav-header">CREW</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-users"></i>
|
||||||
|
<p>
|
||||||
|
User Statistics
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-id-card-clip"></i>
|
||||||
|
<p>
|
||||||
|
User Details
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-graduation-cap"></i>
|
||||||
|
<p>
|
||||||
|
Certificates
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-header">CONTENTMONSTER</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-upload"></i>
|
||||||
|
<p>
|
||||||
|
Current Queue
|
||||||
|
<span class="badge badge-info right">2</span>
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<li class="nav-header">ADMIN AREA</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="{% url "core:admin_vessels" %}" class="nav-link">
|
||||||
|
<i class="nav-icon fas fa-ship"></i>
|
||||||
|
<p>
|
||||||
|
Vessels
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</aside>
|
Loading…
Reference in a new issue