Initial commit
This commit is contained in:
commit
3901201460
34 changed files with 649 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
.idea/
|
0
account/__init__.py
Normal file
0
account/__init__.py
Normal file
BIN
account/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
account/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
account/__pycache__/admin.cpython-312.pyc
Normal file
BIN
account/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
BIN
account/__pycache__/apps.cpython-312.pyc
Normal file
BIN
account/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
BIN
account/__pycache__/models.cpython-312.pyc
Normal file
BIN
account/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
BIN
account/__pycache__/urls.cpython-312.pyc
Normal file
BIN
account/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
BIN
account/__pycache__/views.cpython-312.pyc
Normal file
BIN
account/__pycache__/views.cpython-312.pyc
Normal file
Binary file not shown.
3
account/admin.py
Normal file
3
account/admin.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
6
account/apps.py
Normal file
6
account/apps.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AccountConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "account"
|
0
account/migrations/__init__.py
Normal file
0
account/migrations/__init__.py
Normal file
BIN
account/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
account/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
3
account/models.py
Normal file
3
account/models.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
20
account/templates/account/login.html
Normal file
20
account/templates/account/login.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "facturio/base.html" %}
|
||||
|
||||
{% block title %}Login{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<form class="col-md-6 offset-md-3" action="{% url 'login' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<input type="text" class="form-control" name="username" id="username" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<input type="password" class="form-control" name="password" id="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
15
account/templates/account/me.html
Normal file
15
account/templates/account/me.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "facturio/base.html" %}
|
||||
|
||||
{% block title %}About Me{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mt-4">
|
||||
<h2 class="mb-4">About Me</h2>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Welcome, {{ request.user.username }}!</h5>
|
||||
<p class="card-text">Email: {{ request.user.email }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
5
account/templates/account/register.html
Normal file
5
account/templates/account/register.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
{% extends "facturio/base.html" %}
|
||||
{% block title %}Register{% endblock %}
|
||||
{% block content %}
|
||||
<h1>TODO: register</h1>
|
||||
{% endblock %}
|
3
account/tests.py
Normal file
3
account/tests.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
12
account/urls.py
Normal file
12
account/urls.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from django.http import HttpResponse
|
||||
from django.urls import path, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path("", views.me, name="me"),
|
||||
path("me/", views.me, name="me_exp"),
|
||||
path("login/", views.auth_login, name="login"),
|
||||
path("logout/", views.auth_logout, name="logout"),
|
||||
path("register/", views.auth_register, name="register"),
|
||||
]
|
40
account/views.py
Normal file
40
account/views.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate, login, logout
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpRequest, HttpResponse, JsonResponse
|
||||
from django.shortcuts import redirect, render
|
||||
|
||||
|
||||
def auth_login(req: HttpRequest) -> HttpResponse:
|
||||
if req.method == "POST":
|
||||
username = req.POST["username"]
|
||||
password = req.POST["password"]
|
||||
user = authenticate(req, username=username, password=password)
|
||||
if not user:
|
||||
return JsonResponse(
|
||||
{
|
||||
"message": "Invalid cretendials"
|
||||
},
|
||||
status=401
|
||||
)
|
||||
else:
|
||||
login(req, user)
|
||||
redirect_url = getattr(req.GET, "next", settings.LOGIN_REDIRECT_URL)
|
||||
return redirect(redirect_url)
|
||||
elif req.method == "GET":
|
||||
return render(req, "account/login.html")
|
||||
return HttpResponse(status=405)
|
||||
|
||||
|
||||
@login_required
|
||||
def auth_logout(req: HttpRequest) -> HttpResponse:
|
||||
logout(req)
|
||||
return redirect(settings.LOGOUT_REDIRECT_URL)
|
||||
|
||||
|
||||
def auth_register(req: HttpRequest) -> HttpResponse:
|
||||
return render(req, "account/register.html")
|
||||
|
||||
@login_required
|
||||
def me(req: HttpRequest) -> HttpResponse:
|
||||
return render(req, "account/me.html")
|
BIN
db.sqlite3
Normal file
BIN
db.sqlite3
Normal file
Binary file not shown.
0
facturio/__init__.py
Normal file
0
facturio/__init__.py
Normal file
BIN
facturio/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
facturio/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
facturio/__pycache__/settings.cpython-312.pyc
Normal file
BIN
facturio/__pycache__/settings.cpython-312.pyc
Normal file
Binary file not shown.
BIN
facturio/__pycache__/urls.cpython-312.pyc
Normal file
BIN
facturio/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
BIN
facturio/__pycache__/wsgi.cpython-312.pyc
Normal file
BIN
facturio/__pycache__/wsgi.cpython-312.pyc
Normal file
Binary file not shown.
16
facturio/asgi.py
Normal file
16
facturio/asgi.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
ASGI config for facturio project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "facturio.settings")
|
||||
|
||||
application = get_asgi_application()
|
128
facturio/settings.py
Normal file
128
facturio/settings.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
"""
|
||||
Django settings for facturio project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.0.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.0/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "django-insecure-+l+g3)q1zz2bz7=mz4ys6lhu5uj+=ucj34flm^clo4vb3(wmdp"
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"account.apps.AccountConfig"
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "facturio.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [BASE_DIR / "templates"],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "static",
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "facturio.wsgi.application"
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": BASE_DIR / "db.sqlite3",
|
||||
}
|
||||
}
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||
|
||||
STATIC_URL = "static/"
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
# Login configuration
|
||||
LOGIN_BASE_URL = "/account"
|
||||
LOGIN_URL = f"{LOGIN_BASE_URL}/login"
|
||||
LOGOUT_REDIRECT_URL = f"/"
|
||||
LOGIN_REDIRECT_URL = f"{LOGIN_BASE_URL}/me"
|
34
facturio/urls.py
Normal file
34
facturio/urls.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
"""
|
||||
URL configuration for facturio project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/5.0/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
# TODO: remove
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.shortcuts import render
|
||||
from django.urls import path, include
|
||||
|
||||
|
||||
# TODO: remove
|
||||
def demo(req: HttpRequest) -> HttpResponse:
|
||||
return render(req, "facturio/invoice.html")
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", demo, name="main-page"),
|
||||
path("account/", include("account.urls")),
|
||||
path("admin/", admin.site.urls),
|
||||
]
|
||||
|
16
facturio/wsgi.py
Normal file
16
facturio/wsgi.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
"""
|
||||
WSGI config for facturio project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "facturio.settings")
|
||||
|
||||
application = get_wsgi_application()
|
22
manage.py
Executable file
22
manage.py
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "facturio.settings")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
67
poetry.lock
generated
Normal file
67
poetry.lock
generated
Normal file
|
@ -0,0 +1,67 @@
|
|||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "asgiref"
|
||||
version = "3.7.2"
|
||||
description = "ASGI specs, helper code, and adapters"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"},
|
||||
{file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
|
||||
|
||||
[[package]]
|
||||
name = "django"
|
||||
version = "5.0"
|
||||
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
||||
optional = false
|
||||
python-versions = ">=3.10"
|
||||
files = [
|
||||
{file = "Django-5.0-py3-none-any.whl", hash = "sha256:3a9fd52b8dbeae335ddf4a9dfa6c6a0853a1122f1fb071a8d5eca979f73a05c8"},
|
||||
{file = "Django-5.0.tar.gz", hash = "sha256:7d29e14dfbc19cb6a95a4bd669edbde11f5d4c6a71fdaa42c2d40b6846e807f7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
asgiref = ">=3.7.0"
|
||||
sqlparse = ">=0.3.1"
|
||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
argon2 = ["argon2-cffi (>=19.1.0)"]
|
||||
bcrypt = ["bcrypt"]
|
||||
|
||||
[[package]]
|
||||
name = "sqlparse"
|
||||
version = "0.4.4"
|
||||
description = "A non-validating SQL parser."
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"},
|
||||
{file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["build", "flake8"]
|
||||
doc = ["sphinx"]
|
||||
test = ["pytest", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2023.3"
|
||||
description = "Provider of IANA time zone data"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
files = [
|
||||
{file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"},
|
||||
{file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "1c6ab57fc89858a0923620d3307e9173662bad9b58d9dde4f567267506e03587"
|
16
pyproject.toml
Normal file
16
pyproject.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
[tool.poetry]
|
||||
name = "facturio"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Jakub Kropáček <kropikuba@gmail.com>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
django = "^5.0"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
53
templates/facturio/base.html
Normal file
53
templates/facturio/base.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Facturio - {% block title %}App{% endblock %}</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="#">Facturio</a>
|
||||
|
||||
<!-- Left-aligned items -->
|
||||
<div class="collapse navbar-collapse" id="navbarLeft">
|
||||
<ul class="navbar-nav">
|
||||
<!-- Additional items on the left -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Item 1</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Item 2</a>
|
||||
</li>
|
||||
<!-- Add more items as needed -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Right-aligned login/logout links -->
|
||||
<div class="collapse navbar-collapse justify-content-end" id="navbarRight">
|
||||
<ul class="navbar-nav">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'login' %}">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'register' %}">Register</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-4">
|
||||
{% block content %} {% endblock %}
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
189
templates/facturio/invoice.html
Normal file
189
templates/facturio/invoice.html
Normal file
|
@ -0,0 +1,189 @@
|
|||
<!-- Vaše faktura s aktualizacemi -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="cs">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Faktura</title>
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Ubuntu&display=swap");
|
||||
|
||||
:root {
|
||||
--font-family: "Ubuntu", sans-serif;
|
||||
--main-color: #333;
|
||||
--secondary-color: #888;
|
||||
--border-color: #ddd;
|
||||
--background-color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: var(--font-family);
|
||||
margin: 20px;
|
||||
color: var(--main-color);
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.parties ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.parties li {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.parties h2 {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
padding-bottom: 8px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.invoice-id {
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
|
||||
#invoice {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#invoice th,
|
||||
#invoice td {
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.invoice-total {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.parties-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.parties {
|
||||
width: 48%;
|
||||
}
|
||||
|
||||
#invoice tbody tr {
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.small-col {
|
||||
width: 5%;
|
||||
}
|
||||
.medium-col {
|
||||
width: 15%;
|
||||
}
|
||||
.big-col {
|
||||
width: 25%;
|
||||
}
|
||||
.right-align {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0;
|
||||
margin-top: 20px;
|
||||
color: var(--main-color);
|
||||
background-color: var(--background-color);
|
||||
}
|
||||
|
||||
@media print {
|
||||
@page {
|
||||
size: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 10mm 10mm;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>Faktura <span class="invoice-id">2023-0001</span></h1>
|
||||
</header>
|
||||
|
||||
<section class="parties-section">
|
||||
<div class="parties">
|
||||
<h2>Dodavatel</h2>
|
||||
<ul>
|
||||
<li>Název Vaší společnosti nebo jméno</li>
|
||||
<li>Vaše adresa</li>
|
||||
<li>Vaše město, PSČ</li>
|
||||
<p></p>
|
||||
<li>IČO: 123456789</li>
|
||||
<li>DIČ: CZ123456789 jestli jste plátce DPH</li>
|
||||
<p></p>
|
||||
<li>Bankovní účet: 123-456789</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="parties">
|
||||
<h2>Odběratel</h2>
|
||||
<ul>
|
||||
<li>Název společnosti nebo jméno zákazníka</li>
|
||||
<li>Adresa zákazníka</li>
|
||||
<li>Město zákazníka, PSČ</li>
|
||||
<p></p>
|
||||
<li>IČO zákazníka: 987654321</li>
|
||||
<li>DIČ zákazníka: CZ987654321 jestli je plátce DPH</li>
|
||||
<p></p>
|
||||
<li><strong>Datum vystavení:</strong> 16. prosince 2023</li>
|
||||
<li><strong>Datum splatnosti:</strong> 16. prosince 2023</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Detaily faktury</h2>
|
||||
<table id="invoice">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="small-col">#</th>
|
||||
<th class="small-col">Jednotka</th>
|
||||
<th class="big-col">Popis položky</th>
|
||||
<th class="medium-col right-align">Cena za MJ</th>
|
||||
<th class="medium-col right-align">Celkem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>ks</td>
|
||||
<td>Položka 1</td>
|
||||
<td class="right-align">50,00 Kč</td>
|
||||
<td class="right-align">50,00 Kč</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="invoice-total">
|
||||
<p><strong>Celkem: 100,00 Kč</strong></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>Fyzická osoba zapsaná v živnostenském rejstříku.</p>
|
||||
<p>Fakturu vygenerovala aplikace Facturio</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
Reference in a new issue