switch from bootstrap to tailwind2

This commit is contained in:
Lea 2024-09-09 17:32:55 +02:00
parent 092341e9ed
commit f4242e8935
11 changed files with 2575 additions and 190 deletions

2
.gitignore vendored
View File

@ -3,3 +3,5 @@
.idea
__pycache__
app-2.2.0.js
package-lock.json
node_modules

View File

@ -53,7 +53,7 @@ class SearchForm(Form):
validators.Regexp("^[a-zA-ZäöüßÄÖÜẞ0-9]+$")])
# Define a distance as range input to limit the search area
therapy_distance = IntegerField(
"Distanz (in km)",
"Distanz",
widget=RangeInput(),
default=25,
validators=[validators.InputRequired(), validators.NumberRange(min=0, max=50)]
@ -76,7 +76,8 @@ class SearchForm(Form):
# TODO: find a better name for label
# Choose for how many weeks to show phone times
amount_of_weeks = IntegerField(
"Telefonzeiten für die nächsten Wochen",
# Rest of the label rendered by the frontend (even though not perfect solution)
"Telefonzeiten für die ",
widget=RangeInput(),
default=1,
validators=[validators.InputRequired(), validators.NumberRange(min=1, max=4)]

6
package.json Normal file
View File

@ -0,0 +1,6 @@
{
"devDependencies": {
"daisyui": "^4.12.10",
"tailwindcss": "^3.4.10"
}
}

File diff suppressed because one or more lines are too long

2364
static/css/main.css Normal file

File diff suppressed because it is too large Load Diff

3
static/src/input.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

11
tailwind.config.js Normal file
View File

@ -0,0 +1,11 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./templates/**/*.{html,htm}"],
theme: {
extend: {},
},
plugins: [
require('daisyui'),
],
}

View File

@ -1,29 +1,18 @@
<!doctype html>
<title>{% block title %}{% endblock %} - TheraPy jetzt</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<body>
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">TheraPy</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarColor01">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Home
<span class="visually-hidden">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
<div class="navbar bg-primary text-primary-content justify-center items-center text-center">
<div class="flex">
<a class="btn btn-ghost text-xl" href="#">TheraPy</a>
</div>
</div>
</nav>
<div class=" flex justify-center mr-auto">
<a class="mx-2">Home</a>
<a class="mx-2">About</a>
</div>
</div>
<section class="content">
<header>

View File

@ -1,112 +1,115 @@
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-8 col-md-7 col-sm-6">
<form method="POST" action="/search">
{{ form.csrf_token }}
<fieldset>
<legend>Suche</legend>
<div class="mb-2">
<label for="locationInput" class="form-label mt-4">{{ form.location.label }}</label>
{{ form.location(class="form-control", id="locationInput", placeholder="Standort/PLZ eingeben") }}
{% if form.location.errors %}
<div class="text-danger">
{{ form.location.errors[0] }}
</div>
{% endif %}
<fieldset>
<div class="mt-2">
<label for="distanceRange" class="form-label">{{ form.therapy_distance.label }}</label>
{{ form.therapy_distance(class="form-range", id="distanceRange", min=0, max=50, step=1, oninput="this.nextElementSibling.value = this.value") }}
<output>{{ form.therapy_distance.data or 25 }}</output>
km
{% if form.therapy_distance.errors %}
<div class="text-danger">
{{ form.therapy_distance.errors[0] }}
</div>
{% endif %}
</div>
</fieldset>
</div>
<div class="container mx-auto p-4">
<h1 class="text-3xl font-bold mb-6">Suche</h1>
<form method="POST" action="/search" class="space-y-6">
{{ form.csrf_token }}
<div class="mb-2">
<fieldset>
<legend class="mt-4">{{ form.therapy_type.label }}</legend>
{% for subfield in form.therapy_type %}
<div class="form-check">
{{ subfield(class="form-check-input") }}
<label class="form-check-label" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_type.errors %}
<div class="text-danger">
{{ form.therapy_type.errors[0] }}
</div>
{% endif %}
</fieldset>
</div>
<div class="mb-2">
<fieldset>
<legend class="mt-4">{{ form.therapy_age_range.label }}</legend>
{% for subfield in form.therapy_age_range %}
<div class="form-check">
{{ subfield(class="form-check-input") }}
<label class="form-check-label" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_age_range.errors %}
<div class="text-danger">
{{ form.therapy_age_range.errors[0] }}
</div>
{% endif %}
</fieldset>
</div>
<div class="mb-2">
<fieldset>
<legend class="mt-4">{{ form.therapy_setting.label }}</legend>
{% for subfield in form.therapy_setting %}
<div class="form-check">
{{ subfield(class="form-check-input") }}
<label class="form-check-label" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_setting.errors %}
<div class="text-danger">
{{ form.therapy_setting.errors[0] }}
</div>
{% endif %}
</fieldset>
</div>
<div class="mb-2">
<fieldset>
<div class="mt-2">
<label for="timeRange" class="form-label">{{ form.amount_of_weeks.label }}</label>
{{ form.amount_of_weeks(class="form-range", id="timeRange", min=1, max=4, step=1, oninput="this.nextElementSibling.value = this.value") }}
<output>{{ form.amount_of_weeks.data or 4 }}</output>
nächste(n) Woche(n)
{% if form.therapy_distance.errors %}
<div class="text-danger">
{{ form.amount_of_weeks.errors[0] }}
</div>
{% endif %}
</div>
</fieldset>
</div>
<button type="submit" class="btn btn-primary">Suche</button>
</fieldset>
</form>
<div class="space-y-2">
<label for="locationInput" class="block text-lg font-medium">{{ form.location.label }}</label>
<div class="flex flex-initial items-center space-x-2">
{{ form.location(class="input input-bordered w-full text-lg", id="locationInput", placeholder="Standort/PLZ eingeben") }}
</div>
{% if form.location.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.location.errors[0] }}
</div>
{% endif %}
</div>
</div>
<div class="space-y-2">
<label for="distanceRange" class="block text-lg font-medium">{{ form.therapy_distance.label }}: <span
id="distanceValue">{{ form.therapy_distance.data or 25 }} km</span></label>
<div class="flex items-center">
{{ form.therapy_distance(class="range range-primary flex-grow", id="distanceRange", min=0, max=50, step=1, oninput="document.getElementById('distanceValue').textContent = this.value + ' km'") }}
</div>
{% if form.therapy_distance.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.therapy_distance.errors[0] }}
</div>
{% endif %}
</div>
<div>
<fieldset>
<legend class="block text-lg font-medium">{{ form.therapy_type.label }}</legend>
<div class="space-y-2 mt-2">
{% for subfield in form.therapy_type %}
<div class="flex flex-initial items-center space-x-2">
{{ subfield(class="checkbox checkbox-primary") }}
<label class="text-lg" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_type.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.therapy_type.errors[0] }}
</div>
{% endif %}
</div>
</fieldset>
</div>
<div>
<fieldset>
<legend class="block text-lg font-medium">{{ form.therapy_age_range.label }}</legend>
<div class="space-y-2 mt-2">
{% for subfield in form.therapy_age_range %}
<div class="flex flex-initial items-center space-x-2">
{{ subfield(class="radio radio-primary") }}
<label class="text-lg" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_age_range.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.therapy_age_range.errors[0] }}
</div>
{% endif %}
</div>
</fieldset>
</div>
<div>
<fieldset>
<legend class="block text-lg font-medium">{{ form.therapy_setting.label }}</legend>
<div class="space-y-2 mt-2">
{% for subfield in form.therapy_setting %}
<div class="flex flex-initial items-center space-x-2">
{{ subfield(class="radio radio-primary") }}
<label class="text-lg" for="{{ subfield.id }}">
{{ subfield.label.text }}
</label>
</div>
{% endfor %}
{% if form.therapy_setting.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.therapy_setting.errors[0] }}
</div>
{% endif %}
</div>
</fieldset>
</div>
<div class="space-y-2">
<label for="timeRange" class="block text-lg font-medium">{{ form.amount_of_weeks.label }} <span
id="weeksValue">{{ form.amount_of_weeks.data or 4 }} nächste(n) Woche(n)</span></label>
<div class="flex items-center">
{{ form.amount_of_weeks(class="range range-primary flex-grow", id="timeRange", min=1, max=4, step=1, oninput="document.getElementById('weeksValue').textContent = this.value + ' nächste(n) Woche(n)'") }}
</div>
{% if form.amount_of_weeks.errors %}
<div class="text-red-500 text-sm mt-1">
{{ form.amount_of_weeks.errors[0] }}
</div>
{% endif %}
</div>
<div>
<button type="submit" class="btn btn-primary btn-lg w-full">Suche</button>
</div>
</form>
</div>
{% endblock %}
{% endblock %}

View File

@ -1,16 +1,15 @@
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-11 col-sm-10">
<h2>Keine Ergebnisse</h2>
<div class="alert alert-dismissible alert-primary">
<strong>Keine Telefonzeiten mit gegebenem Standort und Distanz gefunden</strong>
<a href="/" class="alert-link">Zurück zur Suche</a>, um es erneut zu versuchen
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col">
<div class="w-full">
<h2 class="text-2xl font-bold mb-4">Keine Ergebnisse</h2>
<div class="bg-blue-100 border border-blue-400 text-blue-700 px-4 py-3 rounded relative">
<strong class="font-bold">Keine Telefonzeiten mit gegebenem Standort und Distanz gefunden</strong>
<span class="block sm:inline"> <a href="/" class="text-blue-500 underline">Zurück zur Suche</a>, um es erneut zu versuchen</span>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,51 +1,70 @@
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-lg-12 col-md-11 col-sm-10">
<h2>Suchergebnisse</h2>
<div class="container mx-auto px-4 py-6">
<div class="flex flex-col">
<div class="w-full">
<h2 class="text-2xl font-bold mb-4">Suchergebnisse</h2>
{% if doctors is defined and doctors|length %}
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Index</th>
<th scope="col">Name</th>
<th scope="col">Nächster Telefontag</th>
<th scope="col">Nächste Telefonzeit</th>
<th scope="col">Telefonnummer</th>
<th scope="col">Adresse</th>
</tr>
</thead>
<tbody>
{% set day_classes = {
"1": "table-secondary",
"2": "table-success",
"3": "table-info",
"4": "table-light",
"5": "table-primary",
} %}
{% for doctor in doctors %}
<tr class="{{ day_classes.get(doctor.phone_time.start.strftime("%w")) }}">
<th scope="row">{{ doctor.doctor_nr }}</th>
<th scope="row">{{ doctor.doctor_name }}</th>
<td>{{ doctor.phone_time.start.strftime("%A %d.%m") }}</td>
<td>{{ doctor.phone_time.start.strftime("%H:%M") }}
bis {{ doctor.phone_time.end.strftime("%H:%M") }}</td>
<td>{{ doctor.doctor_phone_number }}</td>
<td>{{ doctor.doctor_address }}</td>
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-100">
<tr>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Index
</th>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Name
</th>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Nächster Telefontag
</th>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Nächste Telefonzeit
</th>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Telefonnummer
</th>
<th scope="col"
class="px-6 py-3 text-left text-sm font-medium text-gray-500 uppercase tracking-wider">
Adresse
</th>
</tr>
{% endfor %}
</tbody>
</table>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% set day_classes = {
"1": "bg-gray-200",
"2": "bg-green-100",
"3": "bg-blue-100",
"4": "bg-gray-50",
"5": "bg-blue-100",
} %}
{% for doctor in doctors %}
<tr class="{{ day_classes.get(doctor.phone_time.start.strftime("%w"), 'bg-white') }}">
<th scope="row"
class="px-6 py-4 whitespace-nowrap text-lg font-medium text-gray-900">{{ doctor.doctor_nr }}</th>
<td class="px-6 py-4 whitespace-nowrap text-lg text-gray-500">{{ doctor.doctor_name }}</td>
<td class="px-6 py-4 whitespace-nowrap text-lg text-gray-500">{{ doctor.phone_time.start.strftime("%A %d.%m") }}</td>
<td class="px-6 py-4 whitespace-nowrap text-lg text-gray-500">{{ doctor.phone_time.start.strftime("%H:%M") }}
bis {{ doctor.phone_time.end.strftime("%H:%M") }}</td>
<td class="px-6 py-4 whitespace-nowrap text-lg text-gray-500">{{ doctor.doctor_phone_number }}</td>
<td class="px-6 py-4 whitespace-nowrap text-lg text-gray-500">{{ doctor.doctor_address }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-dismissible alert-primary">
<strong>Keine Telefonzeiten mit gegebenen Daten gefunden</strong>
<a href="/" class="alert-link">Zurück zur Suche</a>, um es erneut zu versuchen
</div>
{% endif %}
<div class="bg-blue-100 border border-blue-400 text-blue-700 px-4 py-3 rounded relative"
role="alert">
<strong class="font-bold">Keine Telefonzeiten mit gegebenen Daten gefunden</strong>
<span class="block sm:inline"> <a href="/" class="text-blue-500 underline">Zurück zur Suche</a>, um es erneut zu versuchen</span>
</div>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% endblock %}