basic dashboard

This commit is contained in:
Flatlogic Bot 2025-12-17 19:16:43 +00:00
parent 26e9533758
commit cd0902b381
13 changed files with 251 additions and 17 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -30,15 +30,22 @@
</div> </div>
<nav class="sidebar-nav"> <nav class="sidebar-nav">
<ul> <ul>
<li class="active"><a href="#"><i data-feather="home"></i> Dashboard</a></li> <li class="{% if request.path == '/' %}active{% endif %}"><a href="{% url 'index' %}"><i data-feather="home"></i> Dashboard</a></li>
<li><a href="#"><i data-feather="briefcase"></i> Projects</a></li> <li class="{% if '/projects' in request.path %}active{% endif %}"><a href="{% url 'projects' %}"><i data-feather="briefcase"></i> Projects</a></li>
<li><a href="#"><i data-feather="file-text"></i> Invoices</a></li> <li><a href="#"><i data-feather="file-text"></i> Invoices</a></li>
<li><a href="#"><i data-feather="users"></i> Clients</a></li> <li><a href="#"><i data-feather="users"></i> Clients</a></li>
<li><a href="#"><i data-feather="settings"></i> Settings</a></li> <li><a href="#"><i data-feather="settings"></i> Settings</a></li>
</ul> </ul>
<ul class="auth-nav"> <ul class="auth-nav">
{% if user.is_authenticated %} {% if user.is_authenticated %}
<li><a href="{% url 'logout' %}"><i data-feather="log-out"></i> Logout</a></li> <li>
<a href="{% url 'logout' %}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">
<i data-feather="log-out"></i> Logout
</a>
<form id="logout-form" action="{% url 'logout' %}" method="post" style="display: none;">
{% csrf_token %}
</form>
</li>
{% else %} {% else %}
<li><a href="{% url 'login' %}"><i data-feather="log-in"></i> Login</a></li> <li><a href="{% url 'login' %}"><i data-feather="log-in"></i> Login</a></li>
<li><a href="{% url 'register' %}"><i data-feather="user-plus"></i> Register</a></li> <li><a href="{% url 'register' %}"><i data-feather="user-plus"></i> Register</a></li>

View File

@ -17,7 +17,51 @@
</div> </div>
</div> </div>
<div class="analytics-grid">
<div class="stat-card">
<div class="stat-info">
<h3>Total projects</h3>
<p class="stat-number">{{ total_projects }}</p>
</div>
<div class="stat-icon">
<i data-feather="archive"></i>
</div>
</div>
<div class="stat-card planned">
<div class="stat-info">
<h3>Planned</h3>
<p class="stat-number">{{ planned_projects }}</p>
</div>
<div class="stat-icon">
<i data-feather="calendar"></i>
</div>
</div>
<div class="stat-card in-progress">
<div class="stat-info">
<h3>In progress</h3>
<p class="stat-number">{{ in_progress_projects }}</p>
</div>
<div class="stat-icon">
<i data-feather="trending-up"></i>
</div>
</div>
<div class="stat-card completed">
<div class="stat-info">
<h3>Completed</h3>
<p class="stat-number">{{ completed_projects }}</p>
</div>
<div class="stat-icon">
<i data-feather="check-circle"></i>
</div>
</div>
</div>
<div class="content-grid"> <div class="content-grid">
{% if request.path == '/projects/' %}
<div class="project-list-header">
<h2>Wszystkie projekty</h2>
</div>
{% endif %}
{% if projects %} {% if projects %}
{% for project in projects %} {% for project in projects %}
<div class="project-card"> <div class="project-card">
@ -30,15 +74,7 @@
<p><strong>Okres:</strong> {{ project.start_date|date:"d M Y" }} - {{ project.end_date|date:"d M Y" }}</p> <p><strong>Okres:</strong> {{ project.start_date|date:"d M Y" }} - {{ project.end_date|date:"d M Y" }}</p>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<div class="participants">
<span>Uczestnicy</span>
<div class="avatars">
<!-- Placeholder avatars -->
<img src="https://i.pravatar.cc/32?u=a" alt="Avatar">
<img src="https://i.pravatar.cc/32?u=b" alt="Avatar">
<img src="https://i.pravatar.cc/32?u=c" alt="Avatar">
</div>
</div>
{% if user.is_authenticated %} {% if user.is_authenticated %}
<a href="{% url 'edit_project' project.id %}" class="btn-view">Edit</a> <a href="{% url 'edit_project' project.id %}" class="btn-view">Edit</a>
<a href="{% url 'delete_project' project.id %}" class="btn-view">Delete</a> <a href="{% url 'delete_project' project.id %}" class="btn-view">Delete</a>

View File

@ -0,0 +1,52 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Projekty - webFirma{% endblock %}
{% block content %}
<div class="main-header">
<h1>Projekty</h1>
<div class="header-actions">
<div class="search-bar">
<i data-feather="search"></i>
<input type="text" placeholder="Search projects...">
</div>
{% if user.is_authenticated %}
<a href="{% url 'add_project' %}" class="btn btn-primary"><i data-feather="plus"></i> Dodaj projekt</a>
{% endif %}
</div>
</div>
<div class="content-grid">
{% if projects %}
{% for project in projects %}
<div class="project-card">
<div class="card-header">
<h3>{{ project.name }}</h3>
<span class="badge status-{{ project.status|lower }}">{{ project.get_status_display }}</span>
</div>
<div class="card-body">
<p><strong>Klient:</strong> {{ project.client }}</p>
<p><strong>Okres:</strong> {{ project.start_date|date:"d M Y" }} - {{ project.end_date|date:"d M Y" }}</p>
</div>
<div class="card-footer">
{% if user.is_authenticated %}
<a href="{% url 'edit_project' project.id %}" class="btn-view">Edit</a>
<a href="{% url 'delete_project' project.id %}" class="btn-view">Delete</a>
{% endif %}
</div>
</div>
{% endfor %}
{% else %}
<div class="empty-state">
<div class="empty-state-icon">
<i data-feather="briefcase"></i>
</div>
<h2>Brak projektów</h2>
<p>Nie masz jeszcze żadnych projektów. Dodaj swój pierwszy projekt, aby rozpocząć.</p>
<a href="{% url 'add_project' %}" class="btn btn-primary">Dodaj projekt</a>
</div>
{% endif %}
</div>
{% endblock %}

View File

@ -1,9 +1,10 @@
from django.urls import path from django.urls import path
from .views import index, add_project, register, edit_project, delete_project from .views import index, add_project, register, edit_project, delete_project, projects
from django.contrib.auth.views import LoginView, LogoutView from django.contrib.auth.views import LoginView, LogoutView
urlpatterns = [ urlpatterns = [
path('', index, name='index'), path('', index, name='index'),
path('projects/', projects, name='projects'),
path('add-project/', add_project, name='add_project'), path('add-project/', add_project, name='add_project'),
path('register/', register, name='register'), path('register/', register, name='register'),
path('login/', LoginView.as_view(template_name='core/login.html'), name='login'), path('login/', LoginView.as_view(template_name='core/login.html'), name='login'),

View File

@ -9,7 +9,20 @@ from .forms import ProjectForm
def index(request): def index(request):
if request.user.is_authenticated: if request.user.is_authenticated:
projects = Project.objects.all().order_by('-start_date') projects = Project.objects.all().order_by('-start_date')
return render(request, 'core/index.html', {'projects': projects})
total_projects = projects.count()
planned_projects = projects.filter(status='planowany').count()
in_progress_projects = projects.filter(status='realizowany').count()
completed_projects = projects.filter(status='zakonczony').count()
context = {
'projects': projects,
'total_projects': total_projects,
'planned_projects': planned_projects,
'in_progress_projects': in_progress_projects,
'completed_projects': completed_projects,
}
return render(request, 'core/index.html', context)
else: else:
return render(request, 'core/landing.html') return render(request, 'core/landing.html')
@ -51,4 +64,11 @@ def register(request):
return redirect('index') return redirect('index')
else: else:
form = UserCreationForm() form = UserCreationForm()
return render(request, 'core/register.html', {'form': form}) return render(request, 'core/register.html', {'form': form})
def projects(request):
if request.user.is_authenticated:
projects = Project.objects.all().order_by('-start_date')
return render(request, 'core/projects.html', {'projects': projects})
else:
return render(request, 'core/landing.html')

View File

@ -319,4 +319,63 @@ body {
.btn-lg { .btn-lg {
padding: 14px 28px; padding: 14px 28px;
font-size: 16px; font-size: 16px;
} }
/* Analytics Cards */
.analytics-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 24px;
margin-bottom: 32px;
}
.stat-card {
background-color: var(--white-color);
border-radius: var(--border-radius);
padding: 24px;
display: flex;
justify-content: space-between;
align-items: center;
border-left: 4px solid var(--primary-color);
box-shadow: var(--card-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.stat-card .stat-info h3 {
margin: 0 0 4px 0;
font-size: 14px;
color: var(--dark-grey);
font-weight: 500;
}
.stat-card .stat-info .stat-number {
margin: 0;
font-size: 28px;
font-weight: 700;
color: var(--text-color);
}
.stat-card .stat-icon {
color: var(--dark-grey);
}
.stat-card .stat-icon svg {
width: 32px;
height: 32px;
}
.stat-card.planned {
border-left-color: #EF6C00;
}
.stat-card.in-progress {
border-left-color: #673AB7;
}
.stat-card.completed {
border-left-color: #2E7D32;
}

View File

@ -319,4 +319,63 @@ body {
.btn-lg { .btn-lg {
padding: 14px 28px; padding: 14px 28px;
font-size: 16px; font-size: 16px;
} }
/* Analytics Cards */
.analytics-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 24px;
margin-bottom: 32px;
}
.stat-card {
background-color: var(--white-color);
border-radius: var(--border-radius);
padding: 24px;
display: flex;
justify-content: space-between;
align-items: center;
border-left: 4px solid var(--primary-color);
box-shadow: var(--card-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.stat-card .stat-info h3 {
margin: 0 0 4px 0;
font-size: 14px;
color: var(--dark-grey);
font-weight: 500;
}
.stat-card .stat-info .stat-number {
margin: 0;
font-size: 28px;
font-weight: 700;
color: var(--text-color);
}
.stat-card .stat-icon {
color: var(--dark-grey);
}
.stat-card .stat-icon svg {
width: 32px;
height: 32px;
}
.stat-card.planned {
border-left-color: #EF6C00;
}
.stat-card.in-progress {
border-left-color: #673AB7;
}
.stat-card.completed {
border-left-color: #2E7D32;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB