first commit

This commit is contained in:
Mateusz Gruszczyński
2025-07-02 11:43:43 +02:00
commit 94efe3bf66
19 changed files with 796 additions and 0 deletions

View File

@ -0,0 +1,24 @@
{% extends 'base.html' %}
{% block title %}Dodaj użytkownika{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2"> Dodaj nowego użytkownika</h2>
<a href="/admin" class="btn btn-outline-secondary">← Powrót do panelu</a>
</div>
<div class="card bg-dark text-white">
<div class="card-body">
<form method="post">
<div class="mb-3">
<input type="text" name="username" placeholder="Nazwa użytkownika" class="form-control" required>
</div>
<div class="mb-3">
<input type="password" name="password" placeholder="Hasło" class="form-control" required>
</div>
<button type="submit" class="btn btn-success w-100">✅ Dodaj użytkownika</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% block title %}Panel administratora{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">⚙️ Panel administratora</h2>
<a href="/" class="btn btn-outline-secondary">← Powrót do strony głównej</a>
</div>
<div class="card bg-dark text-white mb-4">
<div class="card-body">
<p><strong>👤 Liczba użytkowników:</strong> {{ user_count }}</p>
<p><strong>📝 Liczba list:</strong> {{ list_count }}</p>
<p><strong>🛒 Liczba produktów:</strong> {{ item_count }}</p>
</div>
</div>
<div class="d-flex flex-wrap gap-2 mb-4">
<a href="/admin/users" class="btn btn-outline-light">👥 Lista użytkowników</a>
<a href="/admin/add_user" class="btn btn-success"> Dodaj użytkownika</a>
<a href="/admin/delete_all_lists" class="btn btn-danger">🗑️ Usuń wszystkie listy</a>
</div>
<h3 class="mt-4">📄 Wszystkie listy zakupowe</h3>
<div class="table-responsive">
<table class="table table-dark table-striped align-middle">
<thead>
<tr>
<th>ID</th>
<th>Tytuł</th>
<th>Właściciel (ID)</th>
<th>Akcje</th>
</tr>
</thead>
<tbody>
{% for l in all_lists %}
<tr>
<td>{{ l.id }}</td>
<td class="fw-bold">{{ l.title }}</td>
<td>{{ l.owner_id }}</td>
<td>
<a href="{{ url_for('delete_list', list_id=l.id) }}" class="btn btn-sm btn-outline-danger">🗑️ Usuń</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -0,0 +1,32 @@
{% extends 'base.html' %}
{% block title %}Lista użytkowników{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">👥 Lista użytkowników</h2>
<a href="/admin" class="btn btn-outline-secondary">← Powrót do panelu</a>
</div>
<table class="table table-dark table-striped align-middle">
<thead>
<tr>
<th>ID</th>
<th>Login</th>
<th>Akcje</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td class="fw-bold">{{ user.username }}</td>
<td>
<a href="/admin/reset_password/{{ user.id }}" class="btn btn-sm btn-outline-warning me-1">🔑 Resetuj</a>
<a href="/admin/delete_user/{{ user.id }}" class="btn btn-sm btn-outline-danger">🗑️ Usuń</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block title %}Resetuj hasło{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">🔑 Resetuj hasło: {{ user.username }}</h2>
<a href="/admin/users" class="btn btn-outline-secondary">← Powrót do listy użytkowników</a>
</div>
<div class="card bg-dark text-white">
<div class="card-body">
<form method="post">
<div class="mb-3">
<input type="password" name="password" placeholder="Nowe hasło" class="form-control" required>
</div>
<button type="submit" class="btn btn-success w-100">💾 Zapisz nowe hasło</button>
</form>
</div>
</div>
{% endblock %}

30
templates/base.html Normal file
View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>{% block title %}Live Lista Zakupów{% endblock %}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<script src="https://cdn.socket.io/4.6.1/socket.io.min.js"></script>
<script src="{{ url_for('static', filename='js/live.js') }}"></script>
</head>
<body class="bg-dark text-white">
<nav class="navbar navbar-dark bg-dark mb-4">
<div class="container-fluid">
<a class="navbar-brand" href="/">Live Lista Zakupów</a>
<div>
{% if current_user.is_authenticated %}
<a href="{{ url_for('logout') }}" class="btn btn-outline-light">🚪 Wyloguj</a>
{% else %}
<a href="{{ url_for('login') }}" class="btn btn-outline-light">🔑 Zaloguj się</a>
{% endif %}
</div>
</div>
</nav>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>

44
templates/dashboard.html Normal file
View File

@ -0,0 +1,44 @@
{% extends 'base.html' %}
{% block title %}Twoje listy{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">📝 Twoje listy zakupowe</h2>
<div class="d-flex flex-wrap gap-2">
<a href="{{ url_for('index_guest') }}" class="btn btn-outline-light">👀 Tryb gościa</a>
<a href="{{ url_for('index_guest') }}" class="btn btn-success"> Utwórz nową listę</a>
<a href="{{ url_for('logout') }}" class="btn btn-secondary">🚪 Wyloguj</a>
</div>
</div>
{% if lists %}
<div class="table-responsive">
<table class="table table-dark table-striped align-middle">
<thead>
<tr>
<th>ID</th>
<th>Tytuł</th>
<th>Data utworzenia</th>
<th>Akcje</th>
</tr>
</thead>
<tbody>
{% for l in lists %}
<tr>
<td>{{ l.id }}</td>
<td class="fw-bold">{{ l.title }}</td>
<td>{{ l.created_at.strftime('%Y-%m-%d %H:%M') }}</td>
<td>
<a href="{{ url_for('view_list', list_id=l.id) }}" class="btn btn-sm btn-outline-light me-1">📄 Otwórz</a>
<a href="{{ url_for('copy_list', list_id=l.id) }}" class="btn btn-sm btn-outline-secondary">📋 Kopiuj</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p>Nie masz jeszcze żadnych list. Kliknij „Utwórz nową listę”, aby dodać pierwszą!</p>
{% endif %}
{% endblock %}

45
templates/index.html Normal file
View File

@ -0,0 +1,45 @@
{% extends 'base.html' %}
{% block title %}Twoje listy zakupów{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">Twoje listy zakupów</h2>
<a href="{{ url_for('dashboard') }}" class="btn btn-outline-secondary">← Powrót do panelu</a>
</div>
<div class="card bg-dark text-white mb-4">
<div class="card-body">
<form action="/create" method="post" class="row g-2 align-items-center">
<div class="col-sm-5">
<input type="text" name="title" placeholder="Nazwa listy" required class="form-control">
</div>
<div class="col-auto">
<div class="form-check">
<input type="checkbox" name="temporary" class="form-check-input" id="tempCheck">
<label for="tempCheck" class="form-check-label">Tymczasowa (7 dni)</label>
</div>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-success"> Utwórz nową listę</button>
</div>
</form>
</div>
</div>
{% if lists %}
<ul class="list-group">
{% for l in lists %}
<li class="list-group-item bg-dark text-white d-flex justify-content-between align-items-center flex-wrap">
<span class="fw-bold">{{ l.title }}</span>
<div class="mt-2 mt-md-0">
<a href="/list/{{ l.id }}" class="btn btn-sm btn-outline-light me-1">📄 Otwórz</a>
<a href="/copy/{{ l.id }}" class="btn btn-sm btn-outline-secondary">📋 Kopiuj</a>
</div>
</li>
{% endfor %}
</ul>
{% else %}
<p>Nie masz jeszcze żadnych list. Utwórz pierwszą, korzystając z formularza powyżej!</p>
{% endif %}
{% endblock %}

47
templates/list.html Normal file
View File

@ -0,0 +1,47 @@
{% extends 'base.html' %}
{% block title %}{{ list.title }}{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-3 flex-wrap">
<h2 class="mb-2">{{ list.title }}</h2>
<a href="/" class="btn btn-outline-secondary">← Powrót do list</a>
</div>
<div class="card bg-dark text-white mb-4">
<div class="card-body d-flex flex-wrap justify-content-between align-items-center">
<div class="mb-2 mb-md-0">
<strong>Udostępnij link:</strong>
<span class="badge bg-secondary">{{ request.url_root }}share/{{ list.share_token }}</span>
</div>
<button class="btn btn-outline-light btn-sm" onclick="copyLink('{{ request.url_root }}share/{{ list.share_token }}')">
📋 Skopiuj lub udostępnij
</button>
</div>
</div>
<ul id="items" class="list-group mb-3">
{% for item in items %}
<li class="list-group-item bg-dark text-white d-flex justify-content-between align-items-center flex-wrap" id="item-{{ item.id }}">
<div class="d-flex align-items-center flex-wrap gap-2">
<input type="checkbox" onchange="checkItem({{ item.id }})" {% if item.purchased %}checked{% endif %}>
<span id="name-{{ item.id }}">{{ item.name }}</span>
</div>
<div class="mt-2 mt-md-0">
<button class="btn btn-sm btn-outline-warning me-1" onclick="editItem({{ item.id }}, '{{ item.name }}')">✏️ Edytuj</button>
<button class="btn btn-sm btn-outline-danger" onclick="deleteItem({{ item.id }})">🗑️ Usuń</button>
</div>
</li>
{% endfor %}
</ul>
<div class="input-group mb-2">
<input id="newItem" class="form-control" placeholder="Nowy produkt">
<button onclick="addItem({{ list.id }})" class="btn btn-success"> Dodaj</button>
</div>
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
<script>
setupList({{ list.id }}, '{{ current_user.username if current_user.is_authenticated else 'Gość' }}');
</script>
{% endblock %}

20
templates/list_guest.html Normal file
View File

@ -0,0 +1,20 @@
{% extends 'base.html' %}
{% block title %}{{ list.title }} (Gość){% endblock %}
{% block content %}
<h2>{{ list.title }} (Gość)</h2>
<ul id="items" class="list-group mb-3">
{% for item in items %}
<li class="list-group-item bg-dark text-white">
<input type="checkbox" onchange="checkItem({{ item.id }})" {% if item.purchased %}checked{% endif %}> {{ item.name }}
</li>
{% endfor %}
</ul>
<input id="newItem" class="form-control mb-2" placeholder="Nowy produkt">
<button onclick="addItem({{ list.id }})" class="btn btn-primary">Dodaj</button>
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
<a href="/" class="btn btn-secondary mt-3">Powrót</a>
{% endblock %}

24
templates/login.html Normal file
View File

@ -0,0 +1,24 @@
{% extends 'base.html' %}
{% block title %}Logowanie{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">🔒 Logowanie</h2>
<a href="{{ url_for('index_guest') }}" class="btn btn-outline-secondary">← Powrót do list</a>
</div>
<div class="card bg-dark text-white">
<div class="card-body">
<form method="post">
<div class="mb-3">
<input type="text" name="username" placeholder="Login" class="form-control" required>
</div>
<div class="mb-3">
<input type="password" name="password" placeholder="Hasło" class="form-control" required>
</div>
<button type="submit" class="btn btn-success w-100">🔑 Zaloguj</button>
</form>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block title %}Hasło do systemu{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
<h2 class="mb-2">🔑 Hasło do systemu</h2>
<a href="{{ url_for('index_guest') }}" class="btn btn-outline-secondary">← Powrót do list</a>
</div>
<div class="card bg-dark text-white">
<div class="card-body">
<form method="post">
<div class="mb-3">
<input type="password" name="password" placeholder="Hasło" class="form-control" required>
</div>
<button type="submit" class="btn btn-success w-100">🔓 Wejdź</button>
</form>
</div>
</div>
{% endblock %}