diff --git a/src/core/locale/de/LC_MESSAGES/django.po b/src/core/locale/de/LC_MESSAGES/django.po index c392c9da1a197f5fe2d341ec22000def4f12ade0..4649f5476a62c3e009274e7d2cc6ca218af080c5 100644 --- a/src/core/locale/de/LC_MESSAGES/django.po +++ b/src/core/locale/de/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "abuse_report_category-abuse" msgstr "Missbrauch - rechtlich problematische Inhalte" msgid "abuse_report_category-content" -msgstr "Inhalt - Ich denke, der Inhalt ist problematisch" +msgstr "Inhalt - der Inhalt ist problematisch" msgid "abuse_report_category-person" msgstr "Teilnehmende - es gibt ein Problem mit Benutzer*innen" @@ -30,7 +30,7 @@ msgid "abuse_report_category-tech" msgstr "Technisch - ein technisches Problem mit der Website" msgid "abuse_report_category-misc" -msgstr "Verschiedenes - Alles andere" +msgstr "Verschiedenes - alles andere" msgid "All" msgstr "" diff --git a/src/core/locale/en/LC_MESSAGES/django.po b/src/core/locale/en/LC_MESSAGES/django.po index 95eeb5c3b21d076de54cc07009669a76e8f1bb63..794b6c1f7994a644428520491930c3322459fa71 100644 --- a/src/core/locale/en/LC_MESSAGES/django.po +++ b/src/core/locale/en/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgid "abuse_report_category-abuse" msgstr "Abuse - legally problematic content" msgid "abuse_report_category-content" -msgstr "Content - I think the content is problematic" +msgstr "Content - the content is problematic" msgid "abuse_report_category-person" msgstr "Attendee - there is a problem with a user" diff --git a/src/plainui/forms.py b/src/plainui/forms.py index 6770a50cd0ebca5ee9532a15c100ee40021397bd..2f62412aabd617da3e5de06bbd872d2510183a48 100644 --- a/src/plainui/forms.py +++ b/src/plainui/forms.py @@ -251,9 +251,13 @@ class ReportForm(forms.Form): kind_data = forms.CharField(min_length=1, widget=forms.HiddenInput()) lookup_key = forms.CharField(widget=forms.HiddenInput(), required=False) next = forms.CharField(widget=forms.HiddenInput(), required=False) - category = forms.ChoiceField(choices=[(k, v[0]) for k, v in REPORT_CATEGORIES.items() if v[2]], initial='content') - message = forms.CharField(min_length=1, widget=forms.Textarea(), label=_('describe the problem'), required=True) - message2 = forms.CharField(min_length=1, widget=forms.Textarea(), label=_('describe a solution'), required=True) + category = forms.ChoiceField( + choices=[(k, v[0]) for k, v in REPORT_CATEGORIES.items() if v[2] and k != 'tech'], initial='content', help_text=_('Report__category__help') + ) + message = forms.CharField(min_length=1, widget=forms.Textarea(), label=_('describe the problem') + ':', required=True, help_text=_('Report__issue__help')) + message2 = forms.CharField( + min_length=1, widget=forms.Textarea(), label=_('describe a solution') + ':', required=True, help_text=_('Report__solution__help') + ) def __init__(self, *args, request, conf, **kwargs): super().__init__(*args, **kwargs) @@ -319,6 +323,12 @@ class ReportForm(forms.Form): ) +class TechnicalReportForm(ReportForm): + category = forms.ChoiceField( + choices=[(k, v[0]) for k, v in REPORT_CATEGORIES.items() if v[2] and k == 'tech'], initial='tech', help_text=_('Report__category__help') + ) + + class StaticPageBodyForm(forms.ModelForm): class Meta: model = StaticPage diff --git a/src/plainui/jinja2/plainui/report_content.html.j2 b/src/plainui/jinja2/plainui/report_content.html.j2 index 363cdb9d27991110154e189459ad165374918460..890745dc4beeb4726e35dd05b0ebee88b9c60329 100644 --- a/src/plainui/jinja2/plainui/report_content.html.j2 +++ b/src/plainui/jinja2/plainui/report_content.html.j2 @@ -5,7 +5,7 @@ {% extends "plainui/base.html.j2" %} {% block title %} - _("Report Content") - {{ conf.name }} + {{ _("Report Content") }} - {{ conf.name }} {% endblock title %} {% block content %} @@ -23,6 +23,10 @@ <div class="m-0 p-0"> <h2 class="hub-section-title">{{ _("Report Content") }}</h2> <div> + <div class="hub-row mb-4 mt-4"> + <a href="{{ url("plainui:report_tech_content") }}?{{ request.META['QUERY_STRING'] }}" + class="btn btn-secondary">{{ _("Report__technical__forward") }} <i class="bi bi-chevron-right"></i></a> + </div> <form method="post" id="report_content" class="border p-0 mt-11 mb-8{% if form.errors %} border-danger{% endif %}"> diff --git a/src/plainui/jinja2/plainui/report_tech_content.html.j2 b/src/plainui/jinja2/plainui/report_tech_content.html.j2 new file mode 100644 index 0000000000000000000000000000000000000000..304d1c4567810d3c194bfe52a6ea2c6d111d11ce --- /dev/null +++ b/src/plainui/jinja2/plainui/report_tech_content.html.j2 @@ -0,0 +1,67 @@ +{% import "plainui/components/form_elements.html.j2" as formElementsMacro %} +{% import "plainui/components/nav.html.j2" as navMacro with context %} +{% import "plainui/components/wiki.html.j2" as wikiMacro with context %} + +{% extends "plainui/base.html.j2" %} + +{% block title %} + {{ _("Report__technical") }} - {{ conf.name }} +{% endblock title %} + +{% block content %} + {{ navMacro.top_nav(_("Help, there is a Problem...") ) }} + + <div class="hub-vlayout"> + + <div class="hub-row hub-row-equal-height"> + {{ wikiMacro.card('_intro_reportcontent', + class='hub-col-remaining') }} + </div> + + <div class="hub-row"> + <div class="hub-col hub-col-remaining hub-card hub-hlayout-l"> + <div class="m-0 p-0"> + <h2 class="hub-section-title">{{ _("Report__technical") }}</h2> + <div> + + <form method="post" + id="report_tech_content" + class="border p-0 mt-11 mb-8{% if form.errors %} border-danger{% endif %}"> + <div class="p-3"> + {{ csrf_input }} + + {{ formElementsMacro.hidden(form, 'kind') }} + {{ formElementsMacro.hidden(form, 'kind_data') }} + {{ formElementsMacro.hidden(form, 'lookup_key') }} + {{ formElementsMacro.hidden(form, 'next') }} + + {{ formElementsMacro.select(form, 'category') }} + {{ formElementsMacro.textarea(form, 'message') }} + {{ formElementsMacro.textarea(form, 'message2') }} + + {{ formElementsMacro.errors(form) }} + + <p class="my-3"> + {{ _("Your message will be read and processed by one of our angels. We assure you to keep your personal data safe and hidden if not needed to solve your problem.") }} + </p> + + <ul class="d-flex justify-content-center list-unstyled mb-0"> + <li class="mx-2 d-js-only"> + <a onclick="javascript:history.back()" + class="btn btn-xl btn-block btn-transparent" + title="{{ _('Back') }}">{{ _('Back') }}</a> + </li> + <li class="mx-2"> + <button type="submit" class="btn btn-primary px-5">{{ _("Send") }}</button> + </li> + </ul> + </div> + </form> + </div> + </div> + </div> + </div> + + </div> + +{% endblock content %} diff --git a/src/plainui/jinja2/plainui/user.html.j2 b/src/plainui/jinja2/plainui/user.html.j2 index 9b38cc59bd9d78bbb19f8aa9e8ea3a342b6bfaac..e9119a7bb2908a647526b07ec6bc147b5f001058 100644 --- a/src/plainui/jinja2/plainui/user.html.j2 +++ b/src/plainui/jinja2/plainui/user.html.j2 @@ -5,6 +5,7 @@ {% import "plainui/components/nav.html.j2" as navMacro with context %} {% import "plainui/components/tagbox.html.j2" as tagMacros %} {% import "plainui/components/list_events.html.j2" as list_events with context %} +{% import "plainui/components/function_btns.html.j2" as fbtns with context %} {% extends "plainui/base.html.j2" %} @@ -27,6 +28,7 @@ {% if display_user != user and display_user.user_type != 'speaker' %} <a href="{{ url('plainui:personal_message_send_to', recipient=display_user.username) }}" class="hub-btn">{{ _("Send PN") }}</a> + {{ fbtns.report(link, lookup_key=display_user.username, color='outline-secondary') }} {% endif %} {% if display_user == user %} <a href="{{ url('plainui:userprofile') }}" class="hub-btn">{{ _("Edit your profile") }}</a> diff --git a/src/plainui/locale/de/LC_MESSAGES/django.po b/src/plainui/locale/de/LC_MESSAGES/django.po index 1c39633ed7a997d8c7c43904e7edd6f7fbe6e52b..38804f9ead053c7901075973c82bfa4843af6e66 100644 --- a/src/plainui/locale/de/LC_MESSAGES/django.po +++ b/src/plainui/locale/de/LC_MESSAGES/django.po @@ -75,11 +75,20 @@ msgstr "Dieser Benutzer ist nicht mit diesem Ticket verknüpft." msgid "blocked" msgstr "blockiert" +msgid "Report__category__help" +msgstr "Wähle die (am besten) zutreffende Kategorie für dein Anliegen. Die Auswahl entscheidet mit, an welches Team die Meldung geht." + msgid "describe the problem" -msgstr "Beschreibe das Problem" +msgstr "Problem" + +msgid "Report__issue__help" +msgstr "Was genau möchtest du melden? Du hilfst uns, wenn du möglichst genau beschreibst, um was es dir geht. Du kannst das gerne in Stichpunkten tun." msgid "describe a solution" -msgstr "Beschreibe eine Lösung" +msgstr "Lösung" + +msgid "Report__solution__help" +msgstr "Wie, denkst du, sollte damit umgegangen werden? Welche Lösung schlägst du vor? Falls es weiteren Hintergrund braucht, bitte stelle uns diesen zur Verfügung. Auch hiermit hilfst du uns. Wenn dir keine Lösung einfällt, ist das auch okay. Wir werden die Meldung trotzdem bearbeiten. Bitte schreib auch was hin, wenn die Lösung für dich offensichtlich ist. Du kannst auch hier gerne Stichpunkte schreiben." msgid "Wiki__edit__title" msgstr "Seiten-Title" @@ -576,7 +585,7 @@ msgid "new message" msgstr "Neue Nachricht" msgid "Send" -msgstr "senden" +msgstr "Senden" msgid "Personal Message" msgstr "Persönliche Nachricht" @@ -665,8 +674,14 @@ msgstr "Du erhältst eine E-Mail mit einem Reset-Link." msgid "If you have no configured e-mail address, revisit your ticket activation link" msgstr "Falls du keine E-Mail-Adresse konfiguriert hast, klick noch einmal auf deinen Ticket-Aktivierungslink" +msgid "Report__technical__forward" +msgstr "Ein technisches Problem melden" + msgid "Your message will be read and processed by one of our angels. We assure you to keep your personal data safe and hidden if not needed to solve your problem." -msgstr "Deine Nachricht wird von einem unserer Engel gelesen und bearbeitet. Wir versichern Dir, Deine persönlichen Daten sicher und verborgen zu halten, wenn sie nicht zur Lösung des Problems benötigt werden." +msgstr "Deine Nachricht wird von einem unserer Engel gelesen und bearbeitet. Wir versichern dir, deine persönlichen Daten sicher und vertraulich zu behandeln. Sie werden lediglich für Rückfragen genutzt, sollten diese nötig sein." + +msgid "Report__technical" +msgstr "Technisches Problem melden" msgid "Currently Streaming" msgstr "Streaming" diff --git a/src/plainui/locale/en/LC_MESSAGES/django.po b/src/plainui/locale/en/LC_MESSAGES/django.po index 59458723b50e9a01f58a51acd62079b794ce3bd1..f8ef4273cbdd4d40f803bad906cc94b8a6d2f605 100644 --- a/src/plainui/locale/en/LC_MESSAGES/django.po +++ b/src/plainui/locale/en/LC_MESSAGES/django.po @@ -75,11 +75,20 @@ msgstr "" msgid "blocked" msgstr "" +msgid "Report__category__help" +msgstr "Choose the category that best suits your request. You choice will be a factor in determining which team will receive the report." + msgid "describe the problem" -msgstr "" +msgstr "Problem" + +msgid "Report__issue__help" +msgstr "What exactly would you like to report? You will help us if you describe as precisely as possible what you are concerned with. You are welcome to do this in bullet points." msgid "describe a solution" -msgstr "" +msgstr "Solution" + +msgid "Report__solution__help" +msgstr "How, in your opinion, should this be dealt with? Which solution would you suggest? If more background information is required, please provide it. This will help us, too. If you can’t think of a solution, that’s okay. We will still process your report. If the solution is obvious to you, please state it anyway. Again, you are welcome to just use bullet points." msgid "Wiki__edit__title" msgstr "Page Title" @@ -665,8 +674,14 @@ msgstr "" msgid "If you have no configured e-mail address, revisit your ticket activation link" msgstr "" +msgid "Report__technical__forward" +msgstr "Report a technical Issue" + msgid "Your message will be read and processed by one of our angels. We assure you to keep your personal data safe and hidden if not needed to solve your problem." -msgstr "" +msgstr "Your message will be read and processed by one of our angels. We assure you your personal data will be handled securely and confidentially. We will only use it for further clarification, if necessary." + +msgid "Report__technical" +msgstr "Report technical Issue" msgid "Currently Streaming" msgstr "" diff --git a/src/plainui/urls.py b/src/plainui/urls.py index 76190855443c5f60a0034bbc59d375ef663cba54..f50098409045120b3dff51b5f80c40c6bfadaad7 100644 --- a/src/plainui/urls.py +++ b/src/plainui/urls.py @@ -93,6 +93,7 @@ urlpatterns = [ path('sos/', views.SosList.as_view(), name='sos'), path('so/project/<slug:slug>/', views.ProjectView.as_view(self_organized=True), name='so_project'), path('report', views.ReportContentView.as_view(), name='report_content'), + path('tech_report', views.ReportTechContenView.as_view(), name='report_tech_content'), path('user/<slug:user_slug>/', views.UserView.as_view(), name='user'), path('user-by-uuid/<uuid:uuid>/', views.UserByUuidView.as_view(), name='user_by_uuid'), ] diff --git a/src/plainui/views/report.py b/src/plainui/views/report.py index 9e2a129629c14fa618b47d7db3a0ce0c6b62c129..ac69bb66418078eb2210f390841b77862744ed69 100644 --- a/src/plainui/views/report.py +++ b/src/plainui/views/report.py @@ -1,4 +1,4 @@ -__all__ = ('ReportContentView',) +__all__ = ('ReportContentView', 'ReportTechContenView') from django_ratelimit.decorators import ratelimit @@ -12,6 +12,7 @@ from django.views.generic.edit import FormView from plainui.forms import ( ReportForm, + TechnicalReportForm, ) from plainui.views.utils import ( ConferenceRequiredMixin, @@ -62,3 +63,49 @@ class ReportContentView(ConferenceRequiredMixin, FormView): if not url_is_safe: redirect_to = reverse('plainui:index') return redirect(redirect_to) + + +@method_decorator(ratelimit(key='user', rate='1/m', method=ratelimit.UNSAFE), name='dispatch') +@method_decorator(ratelimit(key='ip', rate='5/m', method=ratelimit.UNSAFE), name='dispatch') +class ReportTechContenView(ConferenceRequiredMixin, FormView): + require_user = True + only_published = False + template_name = 'plainui/report_tech_content.html.j2' + form_class = TechnicalReportForm + + def get_context_data(self, **kwargs): + return super().get_context_data(conf=self.conf, disable_share=True, **kwargs) + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['conf'] = self.conf + kwargs['request'] = self.request + return kwargs + + def get_initial(self): + initial = super().get_initial() + initial['kind'] = self.kwargs['kind'] if 'kind' in self.kwargs else self.request.GET.get('kind', '') + initial['kind_data'] = self.kwargs['kind_data'] if 'kind_data' in self.kwargs else self.request.GET.get('kind_data', '') + initial['lookup_key'] = self.kwargs['lookup_key'] if 'lookup_key' in self.kwargs else self.request.GET.get('lookup_key', '') + initial['next'] = self.request.GET.get('next', '') + return initial + + def form_valid(self, form): + form.send_report_mail(self.request) + messages.success( + self.request, + gettext( + 'Thank you for your help to make this platform safer and better! ' + 'Please give us some time to find a solution and keep an eye on your Messages, we may contact you.' + ), + ) + + redirect_to = form.cleaned_data['next'] + url_is_safe = url_has_allowed_host_and_scheme( + url=redirect_to, + allowed_hosts=[self.request.get_host()], + require_https=self.request.is_secure(), + ) + if not url_is_safe: + redirect_to = reverse('plainui:index') + return redirect(redirect_to)