basic dashboard
This commit is contained in:
parent
26e9533758
commit
cd0902b381
BIN
assets/pasted-20251217-191304-2ce2b104.png
Normal file
BIN
assets/pasted-20251217-191304-2ce2b104.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
assets/vm-shot-2025-12-17T19-12-54-230Z.jpg
Normal file
BIN
assets/vm-shot-2025-12-17T19-12-54-230Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
Binary file not shown.
@ -30,15 +30,22 @@
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<ul>
|
||||
<li class="active"><a href="#"><i data-feather="home"></i> Dashboard</a></li>
|
||||
<li><a href="#"><i data-feather="briefcase"></i> Projects</a></li>
|
||||
<li class="{% if request.path == '/' %}active{% endif %}"><a href="{% url 'index' %}"><i data-feather="home"></i> Dashboard</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="users"></i> Clients</a></li>
|
||||
<li><a href="#"><i data-feather="settings"></i> Settings</a></li>
|
||||
</ul>
|
||||
<ul class="auth-nav">
|
||||
{% 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 %}
|
||||
<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>
|
||||
|
||||
@ -17,7 +17,51 @@
|
||||
</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">
|
||||
{% if request.path == '/projects/' %}
|
||||
<div class="project-list-header">
|
||||
<h2>Wszystkie projekty</h2>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if projects %}
|
||||
{% for project in projects %}
|
||||
<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>
|
||||
</div>
|
||||
<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 %}
|
||||
<a href="{% url 'edit_project' project.id %}" class="btn-view">Edit</a>
|
||||
<a href="{% url 'delete_project' project.id %}" class="btn-view">Delete</a>
|
||||
|
||||
52
core/templates/core/projects.html
Normal file
52
core/templates/core/projects.html
Normal 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 %}
|
||||
@ -1,9 +1,10 @@
|
||||
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
|
||||
|
||||
urlpatterns = [
|
||||
path('', index, name='index'),
|
||||
path('projects/', projects, name='projects'),
|
||||
path('add-project/', add_project, name='add_project'),
|
||||
path('register/', register, name='register'),
|
||||
path('login/', LoginView.as_view(template_name='core/login.html'), name='login'),
|
||||
|
||||
@ -9,7 +9,20 @@ from .forms import ProjectForm
|
||||
def index(request):
|
||||
if request.user.is_authenticated:
|
||||
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:
|
||||
return render(request, 'core/landing.html')
|
||||
|
||||
@ -51,4 +64,11 @@ def register(request):
|
||||
return redirect('index')
|
||||
else:
|
||||
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')
|
||||
@ -319,4 +319,63 @@ body {
|
||||
.btn-lg {
|
||||
padding: 14px 28px;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -319,4 +319,63 @@ body {
|
||||
.btn-lg {
|
||||
padding: 14px 28px;
|
||||
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;
|
||||
}
|
||||
|
||||
BIN
staticfiles/pasted-20251217-191304-2ce2b104.png
Normal file
BIN
staticfiles/pasted-20251217-191304-2ce2b104.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
BIN
staticfiles/vm-shot-2025-12-17T19-12-54-230Z.jpg
Normal file
BIN
staticfiles/vm-shot-2025-12-17T19-12-54-230Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
Loading…
x
Reference in New Issue
Block a user