Sfoglia il codice sorgente

dashboard and restore data

tum 1 anno fa
parent
commit
e726df91d1

+ 1 - 0
.gitignore

111
 
111
 
112
 # Security sensitive files
112
 # Security sensitive files
113
 secrets.json
113
 secrets.json
114
+db-init/ob2011.sql

+ 8 - 0
app/coi/settings.py

39
     "django.contrib.messages",
39
     "django.contrib.messages",
40
     "django.contrib.staticfiles",
40
     "django.contrib.staticfiles",
41
     'tailwind',
41
     'tailwind',
42
+    'crispy_forms',
43
+    'crispy_tailwind',
42
     'theme.apps.ThemeConfig',
44
     'theme.apps.ThemeConfig',
43
     'django_browser_reload',
45
     'django_browser_reload',
44
     "core.apps.CoreConfig",
46
     "core.apps.CoreConfig",
45
     "report.apps.ReportConfig",
47
     "report.apps.ReportConfig",
48
+    "sysadmin.apps.SysadminConfig",
49
+    "dashboard.apps.DashboardConfig",
46
 ]
50
 ]
47
 
51
 
48
 MIDDLEWARE = [
52
 MIDDLEWARE = [
170
 INTERNAL_IPS = [
174
 INTERNAL_IPS = [
171
     "127.0.0.1",
175
     "127.0.0.1",
172
 ]
176
 ]
177
+CRISPY_ALLOWED_TEMPLATE_PACKS = "tailwind"
178
+CRISPY_TEMPLATE_PACK = "tailwind"
179
+
180
+LOGIN_URL = '/sysadmin/login/'  # Replace with the path to your login view

+ 2 - 1
app/coi/urls.py

22
 
22
 
23
 urlpatterns = [
23
 urlpatterns = [
24
     path("admin/", admin.site.urls),
24
     path("admin/", admin.site.urls),
25
-    path('', include('report.urls')),  # Include report app's URLs
25
+    path('', include('dashboard.urls')),  # Include report app's URLs
26
     path('report/', include('report.urls')),  # Include report app's URLs
26
     path('report/', include('report.urls')),  # Include report app's URLs
27
+    path('sysadmin/', include('sysadmin.urls')),  # Include report app's URLs
27
     path("__reload__/", include("django_browser_reload.urls")),
28
     path("__reload__/", include("django_browser_reload.urls")),
28
 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
29
 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 0 - 0
app/dashboard/__init__.py


+ 3 - 0
app/dashboard/admin.py

1
+from django.contrib import admin
2
+
3
+# Register your models here.

+ 6 - 0
app/dashboard/apps.py

1
+from django.apps import AppConfig
2
+
3
+
4
+class DashboardConfig(AppConfig):
5
+    default_auto_field = 'django.db.models.BigAutoField'
6
+    name = 'dashboard'

+ 0 - 0
app/dashboard/migrations/__init__.py


+ 3 - 0
app/dashboard/models.py

1
+from django.db import models
2
+
3
+# Create your models here.

+ 58 - 0
app/dashboard/templates/dashboard/index.html

1
+{% extends "base.html" %}
2
+
3
+{% block title %}Dashboard{% endblock %}
4
+
5
+{% block content %}
6
+<div class="container mx-auto px-4 py-6">
7
+    <h1 class="text-3xl font-bold text-gray-800 mb-4">Welcome to the Dashboard</h1>
8
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
9
+        <!-- Card 1 -->
10
+        <div class="bg-white p-6 rounded-lg shadow-md">
11
+            <h2 class="text-xl font-semibold text-gray-700">Total Users</h2>
12
+            <p class="text-gray-600 text-lg mt-2">150</p>
13
+        </div>
14
+        <!-- Card 2 -->
15
+        <div class="bg-white p-6 rounded-lg shadow-md">
16
+            <h2 class="text-xl font-semibold text-gray-700">Reports Generated</h2>
17
+            <p class="text-gray-600 text-lg mt-2">45</p>
18
+        </div>
19
+        <!-- Card 3 -->
20
+        <div class="bg-white p-6 rounded-lg shadow-md">
21
+            <h2 class="text-xl font-semibold text-gray-700">Active Sessions</h2>
22
+            <p class="text-gray-600 text-lg mt-2">20</p>
23
+        </div>
24
+    </div>
25
+
26
+    <div class="mt-8">
27
+        <h2 class="text-2xl font-bold text-gray-800 mb-4">Recent Activities</h2>
28
+        <div class="bg-white rounded-lg shadow-md overflow-hidden">
29
+            <table class="w-full border-collapse border border-gray-200">
30
+                <thead class="bg-gray-100">
31
+                    <tr>
32
+                        <th class="border border-gray-200 px-4 py-2 text-left">Date</th>
33
+                        <th class="border border-gray-200 px-4 py-2 text-left">Activity</th>
34
+                        <th class="border border-gray-200 px-4 py-2 text-left">User</th>
35
+                    </tr>
36
+                </thead>
37
+                <tbody>
38
+                    <tr class="hover:bg-gray-50">
39
+                        <td class="border border-gray-200 px-4 py-2">2024-12-22</td>
40
+                        <td class="border border-gray-200 px-4 py-2">Generated a report</td>
41
+                        <td class="border border-gray-200 px-4 py-2">John Doe</td>
42
+                    </tr>
43
+                    <tr class="hover:bg-gray-50">
44
+                        <td class="border border-gray-200 px-4 py-2">2024-12-21</td>
45
+                        <td class="border border-gray-200 px-4 py-2">Logged in</td>
46
+                        <td class="border border-gray-200 px-4 py-2">Jane Smith</td>
47
+                    </tr>
48
+                    <tr class="hover:bg-gray-50">
49
+                        <td class="border border-gray-200 px-4 py-2">2024-12-20</td>
50
+                        <td class="border border-gray-200 px-4 py-2">Updated profile</td>
51
+                        <td class="border border-gray-200 px-4 py-2">Emily Johnson</td>
52
+                    </tr>
53
+                </tbody>
54
+            </table>
55
+        </div>
56
+    </div>
57
+</div>
58
+{% endblock %}

+ 3 - 0
app/dashboard/tests.py

1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 8 - 0
app/dashboard/urls.py

1
+from django.urls import path
2
+from . import views
3
+
4
+app_name = "dashboard"  # Use this namespace for reverse URL lookups
5
+
6
+urlpatterns = [
7
+    path('', views.index_view, name='index'),
8
+]

+ 6 - 0
app/dashboard/views.py

1
+from django.contrib.auth.decorators import login_required
2
+from django.shortcuts import render
3
+
4
+@login_required
5
+def index_view(request):
6
+    return render(request, 'dashboard/index.html')

+ 0 - 0
app/sysadmin/__init__.py


+ 3 - 0
app/sysadmin/admin.py

1
+from django.contrib import admin
2
+
3
+# Register your models here.

+ 6 - 0
app/sysadmin/apps.py

1
+from django.apps import AppConfig
2
+
3
+
4
+class SysadminConfig(AppConfig):
5
+    default_auto_field = 'django.db.models.BigAutoField'
6
+    name = 'sysadmin'

+ 35 - 0
app/sysadmin/forms.py

1
+# forms.py
2
+from django import forms
3
+from django.contrib.auth.forms import AuthenticationForm
4
+
5
+class CustomLoginForm(AuthenticationForm):
6
+    username = forms.CharField(widget=forms.TextInput(attrs={
7
+        'placeholder': 'Username'
8
+    }))
9
+    password = forms.CharField(widget=forms.PasswordInput(attrs={
10
+        'placeholder': 'Password'
11
+    }))
12
+
13
+# forms.py
14
+from django.contrib.auth.forms import UserCreationForm
15
+from django.contrib.auth.models import User
16
+
17
+class CustomUserCreationForm(UserCreationForm):
18
+    class Meta:
19
+        model = User
20
+        fields = ['username', 'email', 'password1', 'password2']
21
+
22
+    def __init__(self, *args, **kwargs):
23
+        super().__init__(*args, **kwargs)
24
+        self.fields['username'].widget.attrs.update({
25
+            'placeholder': 'Username'
26
+        })
27
+        self.fields['email'].widget.attrs.update({
28
+            'placeholder': 'Email'
29
+        })
30
+        self.fields['password1'].widget.attrs.update({
31
+            'placeholder': 'Password'
32
+        })
33
+        self.fields['password2'].widget.attrs.update({
34
+            'placeholder': 'Confirm Password'
35
+        })

+ 0 - 0
app/sysadmin/migrations/__init__.py


+ 3 - 0
app/sysadmin/models.py

1
+from django.db import models
2
+
3
+# Create your models here.

+ 22 - 0
app/sysadmin/templates/auth/login.html

1
+{% extends "base.html" %}
2
+{% load tailwind_filters %}
3
+{% block title %}Login{% endblock %}
4
+
5
+{% block content %}
6
+<div class="flex items-center justify-center h-screen bg-gray-100">
7
+    <div class="w-full max-w-md p-8 bg-white rounded-lg shadow-md">
8
+        <h2 class="text-2xl font-bold text-center text-gray-700">Login</h2>
9
+        <form method="post" class="space-y-4 mt-6">
10
+            {% csrf_token %}
11
+            {{ form|crispy }}
12
+            <button type="submit" class="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600">
13
+                Login
14
+            </button>
15
+        </form>
16
+        <p class="mt-4 text-center text-gray-600">
17
+            Don't have an account? 
18
+            <a href="{% url 'sysadmin:register' %}" class="text-blue-500 hover:underline">Register</a>
19
+        </p>
20
+    </div>
21
+</div>
22
+{% endblock %}

+ 22 - 0
app/sysadmin/templates/auth/register.html

1
+{% extends "base.html" %}
2
+{% load tailwind_filters %}
3
+{% block title %}Register{% endblock %}
4
+
5
+{% block content %}
6
+<div class="flex items-center justify-center  bg-gray-100">
7
+    <div class="w-full max-w-md p-8 bg-white rounded-lg shadow-md">
8
+        <h2 class="text-2xl font-bold text-center text-gray-700">Register</h2>
9
+        <form method="post" class="space-y-4 mt-6">
10
+            {% csrf_token %}
11
+            {{ form|crispy }}
12
+            <button type="submit" class="w-full bg-green-500 text-white py-2 rounded hover:bg-green-600">
13
+                Register
14
+            </button>
15
+        </form>
16
+        <p class="mt-4 text-center text-gray-600">
17
+            Already have an account? 
18
+            <a href="{% url 'sysadmin:login' %}" class="text-blue-500 hover:underline">Login</a>
19
+        </p>
20
+    </div>
21
+</div>
22
+{% endblock %}

+ 3 - 0
app/sysadmin/tests.py

1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 10 - 0
app/sysadmin/urls.py

1
+from django.urls import path
2
+from . import views
3
+
4
+app_name = "sysadmin"  # Use this namespace for reverse URL lookups
5
+
6
+urlpatterns = [
7
+    path('login/', views.login_view, name='login'),
8
+    path('register/', views.register_view, name='register'),
9
+    path('logout/', views.logout_view, name='logout'),
10
+]

+ 32 - 0
app/sysadmin/views.py

1
+# views.py
2
+from django.contrib.auth import authenticate, login, logout
3
+from django.shortcuts import render, redirect
4
+from .forms import CustomLoginForm, CustomUserCreationForm
5
+
6
+def login_view(request):
7
+    if request.method == "POST":
8
+        form = CustomLoginForm(data=request.POST)
9
+        if form.is_valid():
10
+            user = form.get_user()
11
+            login(request, user)
12
+            return redirect('dashboard:index')  # Redirect to your dashboard
13
+    else:
14
+        form = CustomLoginForm()
15
+
16
+    return render(request, 'auth/login.html', {'form': form, 'hide_sidebar': True})
17
+
18
+def register_view(request):
19
+    if request.method == "POST":
20
+        form = CustomUserCreationForm(request.POST)
21
+        if form.is_valid():
22
+            user = form.save()
23
+            login(request, user)  # Log the user in after creation
24
+            return redirect('dashboard:index')  # Redirect to your dashboard
25
+    else:
26
+        form = CustomUserCreationForm()
27
+
28
+    return render(request, 'auth/register.html', {'form': form, 'hide_sidebar': True})
29
+
30
+def logout_view(request):
31
+    logout(request)  # Logs out the user
32
+    return redirect('sysadmin:login')  # Redirect to the login page after logout

+ 13 - 1
app/templates/base.html

34
                         <span class="self-center text-xl font-semibold dark:text-white">My App</span>
34
                         <span class="self-center text-xl font-semibold dark:text-white">My App</span>
35
                     </a>
35
                     </a>
36
                 </div>
36
                 </div>
37
-                <div class="flex items-center">
37
+                <div class="flex items-center space-x-4">
38
+
39
+                {% if user.is_authenticated %}
40
+                    <!-- Logged-in User -->
41
+                    <span class="text-gray-600 dark:text-gray-300">Hello, {{ user.username }}</span>
42
+                    <a href="{% url 'sysadmin:logout' %}" class="text-blue-500 hover:underline">Logout</a>
43
+                {% else %}
44
+                    <!-- Guest User -->
45
+                    <a href="{% url 'sysadmin:login' %}" class="text-blue-500 hover:underline">Login</a>
46
+                    <a href="{% url 'sysadmin:register' %}" class="text-blue-500 hover:underline">Register</a>
47
+                {% endif %}
38
                     <div class="ml-3">
48
                     <div class="ml-3">
39
                         <button type="button" class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600">
49
                         <button type="button" class="flex text-sm bg-gray-800 rounded-full focus:ring-4 focus:ring-gray-300 dark:focus:ring-gray-600">
40
                             <span class="sr-only">Open user menu</span>
50
                             <span class="sr-only">Open user menu</span>
47
     </nav>
57
     </nav>
48
 
58
 
49
     <!-- Sidebar -->
59
     <!-- Sidebar -->
60
+    {% if not hide_sidebar %}
50
     <aside id="logo-sidebar" class="fixed top-0 left-0 z-40 w-64 h-screen pt-20 transition-transform -translate-x-full bg-white border-r border-gray-200 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700">
61
     <aside id="logo-sidebar" class="fixed top-0 left-0 z-40 w-64 h-screen pt-20 transition-transform -translate-x-full bg-white border-r border-gray-200 sm:translate-x-0 dark:bg-gray-800 dark:border-gray-700">
51
         <div class="h-full px-3 pb-4 overflow-y-auto">
62
         <div class="h-full px-3 pb-4 overflow-y-auto">
52
             <ul class="space-y-2">
63
             <ul class="space-y-2">
56
             </ul>
67
             </ul>
57
         </div>
68
         </div>
58
     </aside>
69
     </aside>
70
+    {% endif %}
59
 
71
 
60
     <!-- Main Content -->
72
     <!-- Main Content -->
61
     <div class="p-4 sm:ml-64">
73
     <div class="p-4 sm:ml-64">

+ 2 - 2
requirements.txt

33
 crispy-bootstrap5  # For Bootstrap 5 support (optional)
33
 crispy-bootstrap5  # For Bootstrap 5 support (optional)
34
 
34
 
35
 # If using TailwindCSS instead of Bootstrap
35
 # If using TailwindCSS instead of Bootstrap
36
-django-tailwind  # For TailwindCSS integration
36
+# django-tailwind  # For TailwindCSS integration
37
 
37
 
38
 # Cache optimization (optional)
38
 # Cache optimization (optional)
39
 django-cacheops  # Caching ORM QuerySets
39
 django-cacheops  # Caching ORM QuerySets
40
-
40
+crispy-tailwind
41
 pandas
41
 pandas
42
 numpy
42
 numpy
43
 scipy
43
 scipy