basic auth
This commit is contained in:
parent
321df5d009
commit
26e9533758
BIN
assets/pasted-20251217-185910-f07115b9.png
Normal file
BIN
assets/pasted-20251217-185910-f07115b9.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
BIN
assets/vm-shot-2025-12-17T18-55-34-630Z.jpg
Normal file
BIN
assets/vm-shot-2025-12-17T18-55-34-630Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
assets/vm-shot-2025-12-17T18-56-07-637Z.jpg
Normal file
BIN
assets/vm-shot-2025-12-17T18-56-07-637Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
@ -180,3 +180,8 @@ if EMAIL_USE_SSL:
|
|||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||||
|
|
||||||
|
LOGIN_URL = 'login'
|
||||||
|
LOGIN_REDIRECT_URL = 'index'
|
||||||
|
LOGOUT_REDIRECT_URL = 'index'
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -36,6 +36,15 @@
|
|||||||
<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">
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<li><a href="{% url 'logout' %}"><i data-feather="log-out"></i> Logout</a></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>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
|
|||||||
45
core/templates/base_public.html
Normal file
45
core/templates/base_public.html
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{% block title %}webFirma{% endblock %}</title>
|
||||||
|
{% if project_description %}
|
||||||
|
<meta name="description" content="{{ project_description }}">
|
||||||
|
<meta property="og:description" content="{{ project_description }}">
|
||||||
|
<meta property="twitter:description" content="{{ project_description }}">
|
||||||
|
{% endif %}
|
||||||
|
{% if project_image_url %}
|
||||||
|
<meta property="og:image" content="{{ project_image_url }}">
|
||||||
|
<meta property="twitter:image" content="{{ project_image_url }}">
|
||||||
|
{% endif %}
|
||||||
|
{% load static %}
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="{% static 'css/custom.css' %}?v={{ deployment_timestamp }}">
|
||||||
|
<script src="https://unpkg.com/feather-icons"></script>
|
||||||
|
{% block head %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="public-layout">
|
||||||
|
<header class="public-header">
|
||||||
|
<div class="logo">
|
||||||
|
<h2>webFirma</h2>
|
||||||
|
</div>
|
||||||
|
<div class="public-actions">
|
||||||
|
<a href="{% url 'login' %}" class="btn">Login</a>
|
||||||
|
<a href="{% url 'register' %}" class="btn btn-primary">Register</a>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="public-content">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
feather.replace()
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
22
core/templates/core/edit_project.html
Normal file
22
core/templates/core/edit_project.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}Edytuj Projekt - webFirma{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="main-header">
|
||||||
|
<h1>Edytuj Projekt</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-grid">
|
||||||
|
<div class="project-card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit" class="btn btn-primary">Zapisz zmiany</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -11,7 +11,9 @@
|
|||||||
<i data-feather="search"></i>
|
<i data-feather="search"></i>
|
||||||
<input type="text" placeholder="Search projects...">
|
<input type="text" placeholder="Search projects...">
|
||||||
</div>
|
</div>
|
||||||
|
{% if user.is_authenticated %}
|
||||||
<a href="{% url 'add_project' %}" class="btn btn-primary"><i data-feather="plus"></i> Dodaj projekt</a>
|
<a href="{% url 'add_project' %}" class="btn btn-primary"><i data-feather="plus"></i> Dodaj projekt</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -37,7 +39,10 @@
|
|||||||
<img src="https://i.pravatar.cc/32?u=c" alt="Avatar">
|
<img src="https://i.pravatar.cc/32?u=c" alt="Avatar">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" class="btn-view">Zobacz projekt</a>
|
{% 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>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
14
core/templates/core/landing.html
Normal file
14
core/templates/core/landing.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends 'base_public.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}Welcome to webFirma{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="landing-page">
|
||||||
|
<div class="hero">
|
||||||
|
<h1>Zarządzaj swoimi projektami</h1>
|
||||||
|
<p>webFirma to proste i intuicyjne narzędzie do zarządzania projektami, fakturami i klientami.</p>
|
||||||
|
<a href="{% url 'register' %}" class="btn btn-primary btn-lg">Zacznij za darmo</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
14
core/templates/core/login.html
Normal file
14
core/templates/core/login.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends 'base_public.html' %}
|
||||||
|
|
||||||
|
{% block title %}Login - webFirma{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h2>Login</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit" class="btn btn-primary">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
14
core/templates/core/register.html
Normal file
14
core/templates/core/register.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{% extends 'base_public.html' %}
|
||||||
|
|
||||||
|
{% block title %}Register - webFirma{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h2>Register</h2>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit" class="btn btn-primary">Register</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@ -1,7 +1,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from .views import index, add_project
|
from .views import index, add_project, register, edit_project, delete_project
|
||||||
|
from django.contrib.auth.views import LoginView, LogoutView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', index, name='index'),
|
path('', index, name='index'),
|
||||||
path('add-project/', add_project, name='add_project'),
|
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'),
|
||||||
|
path('logout/', LogoutView.as_view(), name='logout'),
|
||||||
|
path('edit-project/<int:project_id>/', edit_project, name='edit_project'),
|
||||||
|
path('delete-project/<int:project_id>/', delete_project, name='delete_project'),
|
||||||
]
|
]
|
||||||
@ -1,11 +1,19 @@
|
|||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
|
from django.contrib.auth import login
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
from django.contrib.auth.views import LoginView, LogoutView
|
||||||
from .models import Project
|
from .models import Project
|
||||||
from .forms import ProjectForm
|
from .forms import ProjectForm
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
projects = Project.objects.all().order_by('-start_date')
|
if request.user.is_authenticated:
|
||||||
return render(request, 'core/index.html', {'projects': projects})
|
projects = Project.objects.all().order_by('-start_date')
|
||||||
|
return render(request, 'core/index.html', {'projects': projects})
|
||||||
|
else:
|
||||||
|
return render(request, 'core/landing.html')
|
||||||
|
|
||||||
|
@login_required
|
||||||
def add_project(request):
|
def add_project(request):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = ProjectForm(request.POST)
|
form = ProjectForm(request.POST)
|
||||||
@ -14,4 +22,33 @@ def add_project(request):
|
|||||||
return redirect('index')
|
return redirect('index')
|
||||||
else:
|
else:
|
||||||
form = ProjectForm()
|
form = ProjectForm()
|
||||||
return render(request, 'core/add_project.html', {'form': form})
|
return render(request, 'core/add_project.html', {'form': form})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def edit_project(request, project_id):
|
||||||
|
project = get_object_or_404(Project, pk=project_id)
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = ProjectForm(request.POST, instance=project)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return redirect('index')
|
||||||
|
else:
|
||||||
|
form = ProjectForm(instance=project)
|
||||||
|
return render(request, 'core/edit_project.html', {'form': form, 'project': project})
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def delete_project(request, project_id):
|
||||||
|
project = get_object_or_404(Project, pk=project_id)
|
||||||
|
project.delete()
|
||||||
|
return redirect('index')
|
||||||
|
|
||||||
|
def register(request):
|
||||||
|
if request.method == 'POST':
|
||||||
|
form = UserCreationForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
user = form.save()
|
||||||
|
login(request, user)
|
||||||
|
return redirect('index')
|
||||||
|
else:
|
||||||
|
form = UserCreationForm()
|
||||||
|
return render(request, 'core/register.html', {'form': form})
|
||||||
@ -33,6 +33,16 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-nav {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-header h2 {
|
.sidebar-header h2 {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--primary-dark);
|
color: var(--primary-dark);
|
||||||
@ -251,4 +261,62 @@ body {
|
|||||||
.empty-state p {
|
.empty-state p {
|
||||||
color: var(--dark-grey);
|
color: var(--dark-grey);
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public Layout */
|
||||||
|
.public-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24px 48px;
|
||||||
|
border-bottom: 1px solid var(--medium-grey);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header .logo h2 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-actions .btn {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landing Page */
|
||||||
|
.landing-page .hero {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .hero h1 {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .hero p {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--dark-grey);
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 14px 28px;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
@ -33,6 +33,16 @@ body {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sidebar-nav {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-nav {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-header h2 {
|
.sidebar-header h2 {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--primary-dark);
|
color: var(--primary-dark);
|
||||||
@ -251,4 +261,62 @@ body {
|
|||||||
.empty-state p {
|
.empty-state p {
|
||||||
color: var(--dark-grey);
|
color: var(--dark-grey);
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Public Layout */
|
||||||
|
.public-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24px 48px;
|
||||||
|
border-bottom: 1px solid var(--medium-grey);
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-header .logo h2 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin: 0;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-actions .btn {
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.public-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Landing Page */
|
||||||
|
.landing-page .hero {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .hero h1 {
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page .hero p {
|
||||||
|
font-size: 18px;
|
||||||
|
color: var(--dark-grey);
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 14px 28px;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
BIN
staticfiles/pasted-20251217-185910-f07115b9.png
Normal file
BIN
staticfiles/pasted-20251217-185910-f07115b9.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
BIN
staticfiles/vm-shot-2025-12-17T18-55-34-630Z.jpg
Normal file
BIN
staticfiles/vm-shot-2025-12-17T18-55-34-630Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
staticfiles/vm-shot-2025-12-17T18-56-07-637Z.jpg
Normal file
BIN
staticfiles/vm-shot-2025-12-17T18-56-07-637Z.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
Loading…
x
Reference in New Issue
Block a user