Merge branch 'master' into appdev
authorRadek Czajka <rczajka@rczajka.pl>
Fri, 12 Dec 2025 13:31:37 +0000 (14:31 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Fri, 12 Dec 2025 13:31:37 +0000 (14:31 +0100)
24 files changed:
src/annoy/admin.py
src/annoy/migrations/0019_campaign_banner_books_alter_banner_place_and_more.py [new file with mode: 0644]
src/annoy/models.py
src/annoy/places.py
src/annoy/templates/annoy/banner.html
src/annoy/templatetags/annoy.py
src/catalogue/templates/catalogue/book_detail.html
src/club/admin.py
src/club/forms.py
src/club/models.py
src/club/templates/club/donation_infobox.html [new file with mode: 0644]
src/club/templates/club/donation_step1_form.html
src/club/templates/club/donation_step2.html
src/club/templates/club/donation_step3.html
src/club/templates/club/donation_step_base.html
src/club/templates/club/payment/paypal_invite.html
src/club/templates/payu/rec_widget.html
src/club/urls.py
src/club/views.py
src/wolnelektury/static/2022/styles/layout/_annoy.scss
src/wolnelektury/static/2022/styles/layout/_checkout.scss
src/wolnelektury/static/2022/styles/layout/_navigation.scss
src/wolnelektury/static/js/main.js
src/wolnelektury/templates/user_actions.html

index ab7be6a..ed651b2 100644 (file)
@@ -5,6 +5,9 @@ from modeltranslation.admin import TranslationAdmin
 from . import models
 
 
+admin.site.register(models.Campaign)
+
+
 class BannerAdmin(TranslationAdmin):
     list_display = [
             'place', 'text',
diff --git a/src/annoy/migrations/0019_campaign_banner_books_alter_banner_place_and_more.py b/src/annoy/migrations/0019_campaign_banner_books_alter_banner_place_and_more.py
new file mode 100644 (file)
index 0000000..51e3339
--- /dev/null
@@ -0,0 +1,38 @@
+# Generated by Django 4.0.8 on 2025-11-25 15:13
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('catalogue', '0051_book_has_audio'),
+        ('annoy', '0018_alter_banner_style'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Campaign',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(help_text='Dla zespołu', max_length=255)),
+                ('image', models.FileField(blank=True, upload_to='annoy/banners/', verbose_name='obraz')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='banner',
+            name='books',
+            field=models.ManyToManyField(blank=True, to='catalogue.book'),
+        ),
+        migrations.AlterField(
+            model_name='banner',
+            name='place',
+            field=models.SlugField(choices=[('top', 'U góry wszystkich stron'), ('book-page', 'Strona książki'), ('book-page-center', 'Strona książki, środek'), ('book-text-intermission', 'Przerwa w treści książki'), ('book-fragment-list', 'Obok listy fragmentów książki'), ('blackout', 'Blackout'), ('crisis', 'Kryzysowa')], verbose_name='miejsce'),
+        ),
+        migrations.AddField(
+            model_name='banner',
+            name='campaign',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='annoy.campaign'),
+        ),
+    ]
index 0d88792..6af1cc0 100644 (file)
@@ -8,8 +8,18 @@ from django.utils.timezone import now
 from .places import PLACES, PLACE_CHOICES, STYLES
 
 
+class Campaign(models.Model):
+    name = models.CharField(max_length=255, help_text='Dla zespołu')
+    image = models.FileField('obraz', upload_to='annoy/banners/', blank=True)
+
+    def __str__(self):
+        return self.name
+
+
 class Banner(models.Model):
     place = models.SlugField('miejsce', choices=PLACE_CHOICES)
+    campaign = models.ForeignKey(Campaign, models.PROTECT, null=True, blank=True)
+
     style = models.CharField(
         'styl', max_length=255, blank=True,
         choices=STYLES,
@@ -32,6 +42,8 @@ class Banner(models.Model):
         help_text='Bannery z wyższym priorytetem mają pierwszeństwo.')
     since = models.DateTimeField('od', null=True, blank=True)
     until = models.DateTimeField('do', null=True, blank=True)
+    books = models.ManyToManyField('catalogue.Book', blank=True)
+
     target = models.IntegerField('cel', null=True, blank=True)
     progress = models.IntegerField('postęp', null=True, blank=True)
     show_members = models.BooleanField('widoczny dla członków klubu', default=False)
@@ -49,8 +61,20 @@ class Banner(models.Model):
     def get_text(self):
         return Template(self.text).render(Context())
 
+    def get_image(self):
+        if self.campaign and self.campaign.image:
+            return self.campaign.image
+        else:
+            return self.image
+
+    def is_external(self):
+        return (self.url and
+                not self.url.startswith('/') and
+                not self.url.startswith('https://wolnelektury.pl/')
+                )
+
     @classmethod
-    def choice(cls, place, request, exemptions=True):
+    def choice(cls, place, request, exemptions=True, book=None):
         Membership = apps.get_model('club', 'Membership')
 
         if exemptions and hasattr(request, 'annoy_banner_exempt'):
@@ -68,6 +92,12 @@ class Banner(models.Model):
             until__lt=n
         ).order_by('-priority', '?')
 
+        if book is None:
+            banners = banners.filter(books=None)
+        else:
+            banners = banners.filter(models.Q(books=None) | models.Q(books=book))
+            
+        
         if not request.user.is_authenticated:
             banners = banners.filter(only_authenticated=False)
 
index 8fa767b..0de0483 100644 (file)
@@ -1,6 +1,7 @@
 PLACE_DEFINITIONS = [
     ('top', 'U góry wszystkich stron', True),
     ('book-page', 'Strona książki', False),
+    ('book-page-center', 'Strona książki, środek', False),
     ('book-text-intermission', 'Przerwa w treści książki', False),
     ('book-fragment-list', 'Obok listy fragmentów książki', False),
     ('blackout', 'Blackout', True, (
index 4b2bdcf..9a67fcd 100644 (file)
@@ -11,7 +11,7 @@
               annoy-banner
               annoy-banner_{{ banner.place }}
               annoy-banner-style_{{ banner.style }}
-              {% if banner.image %}with-image{% endif %}
+              {% if banner.get_image %}with-image{% endif %}
               {% if banner.smallfont %}banner-smallfont{% endif %}
               "
         id="annoy-banner-{{ banner.id }}"
            {% if banner.background_color %}background-color: {{ banner.background_color }};{% endif %}
         ">
     {% if not banner.action_label %}
-      <a href="{{ banner.url }}">
+    <a
+      {% if banner.is_external %}target="_blank"{% endif %}
+      href="{{ banner.url }}">
     {% endif %}
     <div class="annoy-banner-inner">
 
-      {% if banner.image %}
-        <img src="{{ banner.image.url }}">
+      {% if banner.get_image %}
+      <div>
+        <img src="{{ banner.get_image.url }}">
+       </div>
       {% endif %}
       <div class="text">
         {{ banner.get_text|safe|linebreaks }}
       </div>
 
       {% if banner.action_label %}
-        <a class="action" href="{{ banner.url }}">
+      <a class="action"
+        {% if banner.is_external %}target="_blank"{% endif %}
+        href="{{ banner.url }}">
           {{ banner.action_label }}
         </a>
       {% endif %}
index 25293f1..cdf4dbc 100644 (file)
@@ -7,8 +7,8 @@ register = template.Library()
 
 
 @register.inclusion_tag('annoy/banner.html', takes_context=True)
-def annoy_banner(context, place):
-    banners = Banner.choice(place, request=context['request'])
+def annoy_banner(context, place, **kwargs):
+    banners = Banner.choice(place, request=context['request'], **kwargs)
     return {
         'banner': banners.first(),
         'closable': PLACES.get(place, False),
index 32a10ad..ccce18b 100644 (file)
@@ -5,9 +5,14 @@
 {% load choose_cites from social_tags %}
 {% load catalogue_tags %}
 {% load likes_book from social_tags %}
+{% load annoy %}
 
 
 {% block global-content %}
+<div class="l-container">
+  {% annoy_banner 'book-page' %}
+  </div>
+
     <div class="l-container">
       <div class="l-breadcrumb">
         <a href="/"><span>{% trans "Strona główna" %}</span></a>
               <button class="l-article__read-more" aria-label="{% trans 'Kliknij aby rozwinąć' %}" data-label="{% trans 'Czytaj więcej' %}" data-action="{% trans 'Zwiń tekst' %}">{% trans 'Czytaj więcej' %}</button>
             </article>
             {% if accessible %}
-            <div class="c-support">
-              <div>
-                <h2>
-                  {% blocktrans trimmed %}
-                    Ta książka jest dostępna dla tysięcy dzieciaków dzięki
-                    <span>darowiznom</span> od osób takich jak <span>Ty</span>!
-                  {% endblocktrans %}
-                </h2>
-                <a href="{% url 'club_join' %}?pk_campaign=layout">{% trans "Dorzuć się!" %}</a>
-              </div>
-              <div class="bg">
-                <!-- img src="{% static '2022/images/dziecko.jpeg' %}" alt="Dorzuć się!" -->
-              </div>
-            </div>
+           {% annoy_banner 'book-page-center' book=book %}
             {% endif %}
           </div>
         {% endwith %}
index 4425928..8620e74 100644 (file)
@@ -11,6 +11,7 @@ from django.utils.safestring import mark_safe
 from fnpdjango.actions import export_as_csv_action
 from modeltranslation.admin import TranslationAdmin
 import annoy.models
+from messaging.models import Contact, Level
 from wolnelektury.utils import YesNoFilter
 from . import models
 
@@ -127,6 +128,11 @@ class CrisisFilter(admin.SimpleListFilter):
         )
 
 
+class OptOutFilter(YesNoFilter):
+    title = 'opt out'
+    parameter_name = 'optout'
+    q = Q(email__in=Contact.objects.filter(level=Level.OPT_OUT).values_list('email', flat=True))
+
 
 class ScheduleAdmin(admin.ModelAdmin):
     form = ScheduleForm
@@ -139,6 +145,7 @@ class ScheduleAdmin(admin.ModelAdmin):
     search_fields = ['email', 'source']
     list_filter = [
         'is_cancelled', 'monthly', 'yearly', 'method',
+        'consent', OptOutFilter,
         PayedFilter, ActiveFilter, ExpiredFilter,
         SourceFilter, CrisisFilter
     ]
index b75877d..e096303 100644 (file)
@@ -35,6 +35,8 @@ class DonationStep1Form(forms.ModelForm):
         self.referer = referer
         super().__init__(*args, **kwargs)
         club = models.Club.objects.first()
+        if self.instance.is_custom_amount():
+            self.fields['custom_amount'].initial = int(self.instance.amount)
         if club is not None:
             self.fields['custom_amount'].widget.attrs['min'] = club.min_amount
 
@@ -50,7 +52,8 @@ class DonationStep1Form(forms.ModelForm):
         return state
 
     def save(self, *args, **kwargs):
-        self.instance.source = self.referer
+        if self.referer is not None:
+            self.instance.source = self.referer
         return super().save(*args, **kwargs)
 
 
index c40428d..7715495 100644 (file)
@@ -161,6 +161,15 @@ class Schedule(models.Model):
         club = Club.objects.first()
         return club.get_description_for_amount(self.amount, self.monthly)
 
+    def is_custom_amount(self):
+        club = Club.objects.first()
+        if not self.amount:
+            return False
+        if self.monthly:
+            return not club.monthlyamount_set.filter(amount=self.amount).exists()
+        else:
+            return not club.singleamount_set.filter(amount=self.amount).exists()
+
     def initiate_payment(self, request):
         return self.get_payment_method().initiate(request, self)
 
diff --git a/src/club/templates/club/donation_infobox.html b/src/club/templates/club/donation_infobox.html
new file mode 100644 (file)
index 0000000..093480b
--- /dev/null
@@ -0,0 +1,10 @@
+<div class="checkout-infobar">
+  <div class="if-monthly">
+    Dziękujemy, że decydujesz się wspierać nas co miesiąc.<br/>
+    Jeśli to pomyłka, możesz zmienić darowiznę na <a class="donation-mod-monthly" data-url="{% url 'donation_set_monthly' schedule.key %}" data-monthly="false" href="{% url 'donation_step1' schedule.key %}">jednorazową</a>.
+  </div>
+  <div class="if-not-monthly">
+    Wolę wspierać co miesiąc! 
+    <a class="donation-mod-monthly" data-url="{% url 'donation_set_monthly' schedule.key %}" data-monthly="true" href="{% url 'donation_step1' schedule.key %}">Zmień na comiesięczną wpłatę.</a>
+  </div>
+</div>
index 033b0ea..4980555 100644 (file)
@@ -1,7 +1,7 @@
 {% load static %}
 {% load i18n %}
 
-<form method="post" action="{% url 'club_join' %}">
+<form method="post" action="{% if schedule %}{% url 'donation_step1' key=schedule.key %}{% else %}{% url 'club_join' %}{% endif %}">
   {% csrf_token %}
   {{ form.errors }}
   <input type="radio" name="switch" id="switch-once" value="single" class="toggle-input" {% if schedule and not schedule.monthly %}checked{% endif %}>
   {% with amounts=club.get_amounts %}
     <div class="l-checkout__payments payments-once wide-spot-{{ amounts.single_wide_spot }}">
       {% for amount in amounts.single %}
-        <div class="l-checkout__payments__box once{% if not schedule.monthly and schedule.amount == amount.amount or not schedule and club.default_single_amount == amount.amount %} is-active{% endif %}{% if amount.wide %} l-checkout__payments__box--special{% endif %} l-checkout__payments__box--{{ amount.box_variant }}">
+        <div class="l-checkout__payments__box once{% if not schedule.monthly and schedule.amount == amount.amount or not schedule and club.default_single_amount == amount.amount %} is-active initial-active{% endif %}{% if amount.wide %} l-checkout__payments__box--special{% endif %} l-checkout__payments__box--{{ amount.box_variant }}">
 
-          <h3>{{ amount.amount }} zł</h3>
           <div class="l-checkout__payments__box__btn-wrp">
-            {% if amount.description %}
-              <p>{{ amount.description|safe }}</p>
-            {% endif %}
-            <button name="single_amount" value="{{ amount.amount }}">{% trans "Wybierz" %}</button>
+            <button name="single_amount" value="{{ amount.amount }}">{{ amount.amount }} zł</button>
           </div>
         </div>
       {% endfor %}
 
     <div class="l-checkout__payments payments-recurring wide-spot-{{ amounts.monthly_wide_spot }}">
     {% for amount in amounts.monthly %}
-      <div class="l-checkout__payments__box{% if schedule.monthly and schedule.amount == amount.amount or not schedule and amount.amount == club.default_monthly_amount %} is-active{% endif %}{% if amount.wide %} l-checkout__payments__box--special{% endif %} l-checkout__payments__box--{{ amount.box_variant }}">
-        <h3>{{ amount.amount }} zł <span>{% trans "/mies." context "kwota na miesiąc" %}</span></h3>
+      <div class="l-checkout__payments__box{% if schedule.monthly and schedule.amount == amount.amount or not schedule and amount.amount == club.default_monthly_amount %} is-active initial-active{% endif %}{% if amount.wide %} l-checkout__payments__box--special{% endif %} l-checkout__payments__box--{{ amount.box_variant }}">
         <div class="l-checkout__payments__box__btn-wrp">
-          {% if amount.description %}
-            <p>{{ amount.description|safe }}</p>
-          {% endif %}
-          <button name="monthly_amount" value="{{ amount.amount }}">{% trans "Wybierz" %}</button>
+          <button name="monthly_amount" value="{{ amount.amount }}">{{ amount.amount }} zł <span> /mies.</span></button>
         </div>
       </div>
     {% endfor %}
@@ -58,7 +50,7 @@
 
   <div class="l-checkout__amount">
     <div class="l-checkout__input">
-      <label for="kwota">{% trans "Inna kwota" %}</label>
+      <label for="id_custom_amount">{% trans "Inna kwota" %}</label>
       {{ form.custom_amount }}
     </div>
     <button>{% trans "Dalej" %}</button>
index 3864ad5..5d60213 100644 (file)
@@ -8,26 +8,27 @@
 
 {% block donation-step-content %}
 
-  <div class="l-checkout__cols">
+  <div class="l-checkout__cols q-is-monthly {% if schedule.monthly %}is-monthly{% endif %}">
     <div class="l-checkout__col">
       <div class="l-checkout__payments__box is-active">
         <h3>
           {{ schedule.amount|floatformat }} zł
-          {% if schedule.monthly %}
-            <span>{% trans "/mies." context "kwota na miesiąc" %}</span>
-          {% endif %}
+          <span class="if-monthly">{% trans "miesięcznie" %}</span>
+          <span class="if-not-monthly">{% trans "jednorazowo" %}</span>
         </h3>
         <img src="{% static '2022/images/checkout-img-3.jpg' %}" alt="">
+       {% if schedule.get_description %}
         <p>{{ schedule.get_description }}</p>
+       {% endif %}
       </div>
     </div>
     <div class="l-checkout__col">
 
+      {% include "club/donation_infobox.html" %}
+      
       <form method='post'>
         {% csrf_token %}
         {{ form.errors }}
-        {{ form.amount }}
-        {{ form.monthly }}
         <div class="l-checkout__form">
           <div class="l-checkout__form__row">
             <div class="l-checkout__input">
index baeee9f..999c708 100644 (file)
@@ -8,21 +8,33 @@
 
 
 {% block donation-step-content %}
-  <div class="l-checkout__cols">
+  <div class="l-checkout__cols q-reload-is-monthly {% if schedule.monthly %}is-monthly{% endif %}">
     <div class="l-checkout__col">
       <div class="l-checkout__payments__box is-active">
         <h3>
           {{ schedule.amount|floatformat }} zł
           {% if schedule.monthly %}
-            <span>{% trans "/mies." context "kwota na miesiąc" %}</span>
+          <span>{% trans "miesięcznie" %}</span>
+         {% else %}
+         <span>{% trans "jednorazowo" %}</span>
           {% endif %}</h3>
           <img src="{% static '2022/images/checkout-img-3.jpg' %}" alt="">
       </div>
     </div>
     <div class="l-checkout__col">
+      {% include "club/donation_infobox.html" %}
+
+      {% if schedule.monthly %}
+      <h3>Darowizna będzie pobierana automatycznie co miesiąc.</h3>
+      <p>Możesz z niej zrezygnować w dowolnej chwili, korzystając z linku który dostaniesz mailem.</p>
+      {% endif %}
+
       <div class="l-checkout__form">
         <div class="l-checkout__form__row full">
-          <div class="iframe">
+
+
+      <div class="iframe">
+           
             {% for method in schedule.get_payment_methods %}
               {% invite_payment method schedule %}
             {% endfor %}
index cede1b4..804ace3 100644 (file)
@@ -31,9 +31,7 @@
       <div class="l-checkout__box__header">
         <img src="{% block donation-jumbo-image %}{% static '2022/images/checkout-img-1.jpg' %}{% endblock %}" alt="Wspieraj Wolne Lektury">
         <div class="l-checkout__box__header__content">
-          <h1>{% trans "Wspieraj Wolne Lektury" %}</h1>
-          <p>{% trans "Dziękujemy, że chcesz razem z nami uwalniać książki!" %}</p>
-          <p>{% trans "Wspieraj Wolne Lektury stałą wpłatą – nawet niewielka ma wielką moc! Możesz też wesprzeć Wolne Lektury jednorazowo." %}</p>
+          {% chunk "donate-top" %}
         </div>
       </div>
       <div class="l-checkout__steps">
@@ -43,7 +41,7 @@
         {% endif %}
         <div class="{% if view.step == 1 %}is-current{% else %}is-completed{% endif %}">
           <span>1</span>
-          <p>{% trans "Rodzaj wsparcia" %}</p>
+          <p>{% trans "Kwota wsparcia" %}</p>
         </div>
         {% if view.step > 1 and view.step != 4 %}
           </a>
@@ -84,6 +82,8 @@
 
     <div class="l-checkout__footer">
       <div class="l-checkout__footer__content">
+        {% chunk 'donate-bottom' %}
+
         <div class="l-checkout__footer__content__item">
           <h3>{% trans "Transparentność jest dla nas bardzo ważna." %}</h3>
           <div>
index 5ac0c4c..baaf09d 100644 (file)
@@ -1,5 +1,11 @@
 {% load i18n static %}
-<h3>{% trans "Wolisz wpłacić przez PayPal?" %}</h3>
+<h3>
+  {% if schedule.monthly %}
+  {% trans "Wolisz ustawić comiesięczną darowiznę przez PayPal?" %}
+  {% else %}
+  {% trans "Wolisz wpłacić przez PayPal?" %}
+  {% endif %}
+</h3>
 <a href="{% url 'paypal_init' schedule.key %}">
   <div class="iframe">
     <img src="{% static 'club/paypal.png' %}" alt="PayPal">
index 13cf53b..be61a53 100644 (file)
@@ -1,5 +1,5 @@
 {% load i18n %}
-<h3>{% trans "Podaj dane karty płatniczej" %}</h3>
+<h3>{% trans "Podaj dane karty płatniczej do comiesięcznej darowizny" %}</h3>
 <div class="iframe">
   <form id="theform" method='POST'  action='{% url "club_payu_rec_payment" schedule.key %}'>
     {% csrf_token %}
index 87bfa5a..c7bab6a 100644 (file)
@@ -18,6 +18,7 @@ urlpatterns = [
     path('plan/<key>/zestawienie/<int:year>/', banner_exempt(views.YearSummaryView.as_view()), name='club_year_summary'),
     path('plan/<key>/rodzaj/', banner_exempt(views.DonationStep1.as_view()), name='donation_step1'),
     path('plan/<key>/dane/', banner_exempt(views.DonationStep2.as_view()), name='donation_step2'),
+    path('plan/<key>/ustaw-miesiecznie/', views.set_monthly, name='donation_set_monthly'),
 
     path('przylacz/<key>/', views.claim, name='club_claim'),
     path('anuluj/<key>/', views.cancel, name='club_cancel'),
index b2657e6..503a431 100644 (file)
@@ -4,7 +4,7 @@
 from django.conf import settings
 from django.contrib.auth.decorators import login_required, permission_required
 from django.db.models import Sum
-from django.http import HttpResponse, HttpResponseRedirect
+from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
 from django.shortcuts import get_object_or_404, render
 from django.urls import reverse
 from django.utils.decorators import method_decorator
@@ -30,6 +30,7 @@ class ClubView(TemplateView):
 
 
 
+@method_decorator(never_cache, name='dispatch')
 class DonationStep1(UpdateView):
     queryset = models.Schedule.objects.filter(payed_at=None)
     form_class = forms.DonationStep1Form
@@ -46,6 +47,7 @@ class DonationStep1(UpdateView):
         return reverse('donation_step2', args=[self.object.key])
 
 
+@method_decorator(never_cache, name='dispatch')
 class DonationStep2(UpdateView):
     queryset = models.Schedule.objects.filter(payed_at=None)
     form_class = forms.DonationStep2Form
@@ -59,6 +61,17 @@ class DonationStep2(UpdateView):
         return c
 
 
+def set_monthly(request, key):
+    schedule = get_object_or_404(models.Schedule, payed_at=None, key=key)
+    if request.POST:
+        schedule.monthly = request.POST.get('monthly') == 'true'
+        schedule.save(update_fields=['monthly'])
+    return JsonResponse({
+        "amount": schedule.amount,
+        "monthly": schedule.monthly,
+    })
+    
+
 class JoinView(CreateView):
     form_class = forms.DonationStep1Form
     template_name = 'club/donation_step1.html'
index 70704f3..5c76498 100644 (file)
        }
     }
 }
+
+
+
+.annoy-banner_book-page {
+    background-color: #ffd430;
+    color: #083F4D;
+    border-radius: 10px;
+    padding: 15px 20px;
+    margin-top: 20px;
+
+    .annoy-banner-inner {
+       display: flex;
+       flex-direction: row;
+       gap: 20px;
+       align-items: flex-start;
+       justify-content: space-between;
+
+       p {
+           margin: 0;
+       }
+       a {
+           line-height: 1.35;
+           color: #c32721;
+           white-space: nowrap;
+           border: solid #c32721;
+           border-width: 0 0 1px;
+
+           &:hover {
+               text-decoration: none;
+               border-bottom-width: 2px;
+           }
+       }
+    }
+}
+
+.annoy-banner_book-page-center {
+    background: white;
+    margin-top: 50px;
+    padding: 20px;
+    border: 1px solid #018189;
+    border-radius: 15px;
+    color:#018189;
+
+    .annoy-banner-inner {
+       display: flex;
+       gap: 15px;
+       align-items: center;
+
+       img {
+           width: 150px;
+       }
+       p {
+           margin: 0;
+       }
+    }
+}
index 593794b..28fd1ce 100644 (file)
     }
   }
   button {
-    height: 56px;
+      margin: 0;
+      font-family: "Source Sans Pro",sans-serif;
+    font-weight: bold;
+    font-size: 44px;
+    line-height: 130%;
+    letter-spacing: -0.01em;
+    height: 90px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: all $ease-out 250ms;
+
     background: #FFFFFF;
     border: 1px solid #92BD39;
     border-radius: 3px;
     width: 100%;
     outline: 0;
     cursor: pointer;
-    font-weight: 600;
-    font-size: 16px;
-    line-height: 24px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
     text-align: center;
     color: #083F4D;
-    transition: background $ease-out 250ms;
 
-    @include rwd($break-flow) {
-        font-size: 20px;
-        line-height: 25px;
+    span {
+      font-weight: 600;
+      font-size: 25px;
+      line-height: 200%;
+      letter-spacing: -0.01em;
+      color: #92BD39;
+      margin-left: 10px;
+      transition: opacity $ease-out 250ms;
     }
     
     &:hover {
       &:hover {
         background: #83AD2B;
       }
+      span {
+         color: white;
+      }
     }
   }
 
         }
     }
 }
+
+
+.if-monthly { display: none; }
+.is-monthly {
+    .if-monthly {
+       display: block;
+    }
+    .if-not-monthly {
+       display: none;
+    }
+}
+
+
+.checkout-infobar {
+    margin: 0 0 20px;
+    padding: 20px;
+    border-radius: 10px;
+    border: 1px solid #edc016;
+    background: #edc016;
+}
index c4d4f7a..a47875b 100644 (file)
@@ -161,6 +161,15 @@ body {
               color: white;
           }
       }
+
+      .menubar-donate {
+         color: #fff;
+         background: #c92834;
+         padding: 9px 20px 11px;
+         font-weight: 600;
+         margin-right: 20px;
+         border-radius: 15px;
+      }
   }
 
     .user {
@@ -267,6 +276,10 @@ body {
               display: block;
               left: 16px;
           }
+
+         .menubar-donate {
+             display: none;
+         }
       }
   }
 }
index 45a4197..9821c77 100644 (file)
         $('input', container).val($(this).val());
         $('.is-active', container).removeClass('is-active');
         $(this).closest('.l-checkout__payments__box').addClass('is-active');
-        $('#kwota').val('');
-        return false;
+        $('#id_custom_amount').val('');
+    });
+
+    $('#id_custom_amount').on('input', function() {
+       if ($(this).val() > 0) {
+           $('.l-checkout__payments__box.is-active').removeClass('is-active');
+       } else {
+           $('.l-checkout__payments__box.initial-active').addClass('is-active');
+       }
+    });
+
+    $('.donation-mod-monthly').on('click', function() {
+       $.ajax({
+           method: 'POST',
+           data: {
+               csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
+               monthly: $(this).data('monthly'),
+           },
+           url: $(this).data('url'),
+           success: function(data) {
+               if ($(".q-reload-is-monthly").length) {
+                   window.location.reload()
+               } else {
+                   $(".q-is-monthly").toggleClass('is-monthly', data.monthly);
+               }
+           }
+       });
+       return false;
     });
     
 })();
index 7b9ea2d..1a804f1 100644 (file)
     </ul>
   </div>
   <a href="{% url 'user_settings' %}" class="user">
-    {% if request.user.is_staffs %}
+    {% if request.user.is_staff %}
       <img src="{% static '2022/images/icons/user-staff.svg' %}">
     {% elif request.user.membership %}
       <img src="{% static '2022/images/icons/user-vip.svg' %}">
     {% else %}
       <img src="{% static '2022/images/icons/user.svg' %}">
     {% endif %}
 </a>
+ </a>
 {% else %}
   <div class="l-navigation__login">
     <a id="login-link" href='{% url 'login' %}?next={{ request.path }}'>{% trans "Zaloguj się" %}</a>
@@ -38,3 +38,6 @@
     <a href='{% url 'register' %}?next={{ request.path }}'>{% trans "Załóż konto" %}</a>
   </div>
 {% endif %}
+
+<a href="/pomagam/?pk_campaign=menubar" class="menubar-donate">Wspieram!</a>
+