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
|
||||
|
||||
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="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>
|
||||
{% 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>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
@ -37,7 +39,10 @@
|
||||
<img src="https://i.pravatar.cc/32?u=c" alt="Avatar">
|
||||
</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>
|
||||
{% 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 .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 = [
|
||||
path('', index, name='index'),
|
||||
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 .forms import ProjectForm
|
||||
|
||||
def index(request):
|
||||
projects = Project.objects.all().order_by('-start_date')
|
||||
return render(request, 'core/index.html', {'projects': projects})
|
||||
if request.user.is_authenticated:
|
||||
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):
|
||||
if request.method == 'POST':
|
||||
form = ProjectForm(request.POST)
|
||||
@ -14,4 +22,33 @@ def add_project(request):
|
||||
return redirect('index')
|
||||
else:
|
||||
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;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.auth-nav {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar-header h2 {
|
||||
font-weight: 700;
|
||||
color: var(--primary-dark);
|
||||
@ -251,4 +261,62 @@ body {
|
||||
.empty-state p {
|
||||
color: var(--dark-grey);
|
||||
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;
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.auth-nav {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sidebar-header h2 {
|
||||
font-weight: 700;
|
||||
color: var(--primary-dark);
|
||||
@ -251,4 +261,62 @@ body {
|
||||
.empty-state p {
|
||||
color: var(--dark-grey);
|
||||
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