diff --git a/src/plainui/jinja2.py b/src/plainui/jinja2.py index 63ba43199901a8c0bffc6140838a0507350d835d..520546dfc10265a6d76db8d0a03584216746a6f7 100644 --- a/src/plainui/jinja2.py +++ b/src/plainui/jinja2.py @@ -12,7 +12,7 @@ from django.contrib.humanize.templatetags.humanize import NaturalTimeFormatter from jinja2 import contextfunction, Environment -from core.models import PlatformUser +from core.models import PlatformUser, UserBadge def url(name, *args, current_app=None, **kwargs): @@ -35,6 +35,13 @@ def num_of_unread_messages(request): return user.received_messages.filter(was_read=False).count() +def num_of_pending_badges(request): + user = request.user + if not user.is_authenticated: + return 0 + return len(UserBadge.objects.filter(user=user, accepted_by_user=False).select_related('badge')) + + def custom_timedelta(tdelta): return NaturalTimeFormatter.string_for(tdelta) @@ -143,6 +150,7 @@ def environment(**options): 'get_messages': get_messages, 'json_script': json_script, 'num_of_unread_messages': num_of_unread_messages, + 'num_of_pending_badges': num_of_pending_badges, 'static': static, 'url': url, 'show_vars': show_vars, diff --git a/src/plainui/jinja2/plainui/assembly.html b/src/plainui/jinja2/plainui/assembly.html index 0ccd83410e45cbc18f5376a8ac61ad74c3138652..8939a07391e7ddee0480529a8e4eefc8a3eb834d 100644 --- a/src/plainui/jinja2/plainui/assembly.html +++ b/src/plainui/jinja2/plainui/assembly.html @@ -66,7 +66,7 @@ <div class="border m-0 p-0 bg-opaque"> <h2 class="bg-white text-center text-dark m-0 px-3 py-1">{{ _("assembly badges") }}</h2> - <div class="row p-3"> + <div class="badges-gallery p-3"> {% if not badges %} {{ _("No badges publicly available.") }} {% endif %} diff --git a/src/plainui/jinja2/plainui/components/badge_elements.html b/src/plainui/jinja2/plainui/components/badge_elements.html index 73a14711a937ee8ff6610e4175f6b9b8da0b7d6b..7cc1cd576edb1b6ec478f4b220d54e0476b52930 100644 --- a/src/plainui/jinja2/plainui/components/badge_elements.html +++ b/src/plainui/jinja2/plainui/components/badge_elements.html @@ -1,64 +1,62 @@ {% import "plainui/components/form_elements.html" as form_elements %} {% macro userBadge(badge_link, showButtons, showRest) -%} {% if badge_link %} - <div class="col-3 p-2" style="max-width: 256px!important; width: 256px!important;"> - <div class="card box-shadow w-100"> - <div > - {% if badge_link.badge.image %} - <img class="card-img-top" - alt="Thumbnail Badge {{badge_link.badge.name}}" - src="{{badge_link.badge.image.url}}" - data-holder-rendered="true"> - {% else %} - <img class="card-img-top" - alt="Thumbnail Badge {{badge_link.badge.name}}" - src="{{ static('plainui/img/rc3-no-avatar-plattform-active.jpeg') }}" - data-holder-rendered="true"> - {% endif %} - </div> - <div class="card-body card-text"> - <h4 class="font-sans-serif m-2">{{badge_link.badge.name}}</h4> - <!-- Buttonm Revoke --> - {% if showButtons %} + <div class="card box-shadow w-100"> + <div class="bg-opaque"> + {% if badge_link.badge.image %} + <img class="card-img-top aspect-ratio-16by9" + alt="Thumbnail Badge {{badge_link.badge.name}}" + src="{{badge_link.badge.image.url}}" + data-holder-rendered="true"> + {% else %} + <img class="card-img-top aspect-ratio-16by9" + alt="Thumbnail Badge {{badge_link.badge.name}}" + src="{{ static('plainui/img/rc3-no-avatar-plattform-active.jpeg') }}" + data-holder-rendered="true"> + {% endif %} + </div> + <div class="card-body card-text"> + <h4 class="font-sans-serif m-2">{{badge_link.badge.name}}</h4> + <!-- Buttonm Revoke --> + {% if showButtons %} + <form method="POST"> + {{ csrf_input }} + <div class="form-row align-items-center"> + <input name="badgeid" hidden class="form-control mb-2 m-2" value={{badge_link.badge.id}} > + {% if badge_link.accepted_by_user %} + <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Revoke Badge") }}''> + {% else %} + <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Accept Badge") }}''> + {% endif %} + </div> + </form> + {% if badge_link.accepted_by_user %} <form method="POST"> - {{ csrf_input }} <div class="form-row align-items-center"> + {{ csrf_input }} <input name="badgeid" hidden class="form-control mb-2 m-2" value={{badge_link.badge.id}} > - {% if badge_link.accepted_by_user %} - <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Revoke Badge") }}''> - {% else %} - <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Accept Badge") }}''> - {% endif %} + <h6 class="m-2 font-sans-serif mb-0">{{ _("Visibility") }}</h6> + <select + class="form-control p-1 m-2 mt-1" + name="visibility" + > + <option value="private" {% if badge_link.visibility == "private" %} selected="selected" {% endif %}>{{ _( "private" ) }}</option> + <option value="public" {% if badge_link.visibility == "public" %} selected="selected" {% endif %}>{{ _( "public" ) }}</option> + <option value="friends" {% if badge_link.visibility == "friends" %} selected="selected" {% endif %}>{{ _( "friends" ) }}</option> + <option value="club" {% if badge_link.visibility == "club" %} selected="selected" {% endif %}>{{ _( "club" ) }}</option> + <option value="clubANDfriends" {% if badge_link.visibility == "clubANDfriends" %} selected="selected" {% endif %}> + {{ _( "friends and club" ) }} + </option> + </select> + <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Save visibility") }}''> </div> </form> - {% if badge_link.accepted_by_user %} - <form method="POST"> - <div class="form-row align-items-center"> - {{ csrf_input }} - <input name="badgeid" hidden class="form-control mb-2 m-2" value={{badge_link.badge.id}} > - <h6 class="m-2 font-sans-serif mb-0">{{ _("Visibility") }}</h6> - <select - class="form-control p-1 m-2 mt-1" - name="visibility" - > - <option value="private" {% if badge_link.visibility == "private" %} selected="selected" {% endif %}>{{ _( "private" ) }}</option> - <option value="public" {% if badge_link.visibility == "public" %} selected="selected" {% endif %}>{{ _( "public" ) }}</option> - <option value="friends" {% if badge_link.visibility == "friends" %} selected="selected" {% endif %}>{{ _( "friends" ) }}</option> - <option value="club" {% if badge_link.visibility == "club" %} selected="selected" {% endif %}>{{ _( "club" ) }}</option> - <option value="clubANDfriends" {% if badge_link.visibility == "clubANDfriends" %} selected="selected" {% endif %}> - {{ _( "friends and club" ) }} - </option> - </select> - <input type="submit" class="btn btn-primary p-2 mb-2 m-2" value='{{ _("Save visibility") }}''> - </div> - </form> - {% endif %} - {% else %} - {% if showRest %} - <h6 class="m-2 font-sans-serif mb-0"><small class="fs-medium">{{ _("Visibility") }}:<br /></small> {{ _(badge_link.visibility) }}</h6> - {% endif %} {% endif %} - </div> + {% else %} + {% if showRest %} + <h6 class="m-2 font-sans-serif mb-0"><small class="fs-medium">{{ _("Visibility") }}:<br /></small> {{ _(badge_link.visibility) }}</h6> + {% endif %} + {% endif %} </div> </div> {% endif %} @@ -66,16 +64,15 @@ {% macro badge(badge) -%} {% if badge %} - <div class="col-3 p-2" style="max-width: 256px!important; width: 256px!important;"> - <div class="card box-shadow w-100"> - <div > + <div class="card box-shadow w-100"> + <div class="bg-opaque"> {% if badge.image %} - <img class="card-img-top" + <img class="card-img-top aspect-ratio-16by9" alt="Thumbnail Badge {{badge.name}}" src="{{badge.image.url}}" data-holder-rendered="true"> {% else %} - <img class="card-img-top" + <img class="card-img-top aspect-ratio-16by9" alt="Thumbnail Badge {{badge.name}}" src="{{ static('plainui/img/rc3-no-avatar-plattform-active.jpeg') }}" data-holder-rendered="true"> @@ -86,7 +83,6 @@ <h4 class="font-sans-serif m-2">{{badge.name}}</h4> </p> </div> - </div> </div> {% endif %} {%- endmacro %} diff --git a/src/plainui/jinja2/plainui/header.html b/src/plainui/jinja2/plainui/header.html index 4186c3791b88a1e20a720a2c8acf28308c473563..aefca5fa327fe71bad3334a883256f0a71b9dd46 100644 --- a/src/plainui/jinja2/plainui/header.html +++ b/src/plainui/jinja2/plainui/header.html @@ -51,12 +51,22 @@ > {{ _("board") }} </a> + {% set num_of_pending_badges = num_of_pending_badges(request) -%} <a class="rc3-header-link ml-3" - href="{{ url('plainui:userprofile') }}" + {% if num_of_pending_badges %} + href="{{ url('plainui:userprofile') }}#badges" + {% else %} + href="{{ url('plainui:userprofile') }}" + {% endif %} title="{{ _('profile') }}" > {{ _('profile') }} + {% if num_of_pending_badges %} + <span class="rc3-header__badge"> + {{ num_of_pending_badges }} + </span> + {% endif %} </a> </div> <div class="d-flex justify-content-end"> diff --git a/src/plainui/jinja2/plainui/manage_badges.html b/src/plainui/jinja2/plainui/manage_badges.html index 54b3c09d60688fe38f5d67beaf28cbd91d258cb1..323d92cdfcddcc1a60403c4ade4cff4da6b4ac68 100644 --- a/src/plainui/jinja2/plainui/manage_badges.html +++ b/src/plainui/jinja2/plainui/manage_badges.html @@ -10,36 +10,28 @@ {{ titleMacro.title( _("Manage Badges") ) }} -<div class="row m-0"> - <div class="col-12 p-1"> +<div class=""> + <p class="p-2"> <a class="a a-bold" href="{{ url('plainui:userprofile') }}"> {{ _("Back") }} </a> - </div> + </p> - <div class="row m-0 mb-3"> - <form method="POST" class="horizontal" action="{{ url('plainui:redeem_badge') }}"> - {{ csrf_input }} - <div class="form-row align-items-center"> - <div class="col-12"> - <h3 class="font-sans-serif m-1">{{ _("Redeem Token") }}</h3> - </div> - <div class="col-9"> - <input name="token" class="form-control mb-2" placeholder="Token" > - </div> - <div class="col-3"> - <input type="submit" class="btn btn-primary mb-2"> - </div> - </div> - </form> - </div> + <h2 class="m-1 w-100">{{ _("Redeem Token") }}</h2> + <form method="POST" class="" action="{{ url('plainui:redeem_badge') }}"> + {{ csrf_input }} + <input name="token" class="form-control mb-2 w-100" placeholder="Token" > + <input type="submit" class="btn btn-primary mb-2" value="{{ _('Redeem') }}"> + </form> </div> -<div class="border m-0 my-5 p-0"> +<hr class="rc3-spacer"> + +<div class="border m-0 my-5 p-0 bg-opaque"> <h3 class="w-100 bg-white text-dark text-center m-0 py-2">{{ _("Pending Badges") }}</h3> - <div class="row container-fluid content-row p-3"> + <div class="badges-gallery container-fluid p-3"> {% if not badges_not_accepted %} - <div class="row my-5 p-6"> + <div class=""> {{ _("No badges are waiting for approval.") }} </div> {% endif %} @@ -51,11 +43,11 @@ <hr class="rc3-spacer"> -<div class="border m-0 my-5 p-0 "> +<div class="border m-0 my-5 p-0 bg-opaque"> <h3 class="w-100 bg-white text-dark text-center m-0 py-2">{{ _("Accepted Badges") }}</h3> - <div class="row container-fluid content-row p-3"> + <div class="badges-gallery container-fluid p-3"> {% if not badges_accepted %} - <div class="row my-5 p-6"> + <div class="row "> {{ _("No badges Accepted.") }} </div> {% endif %} diff --git a/src/plainui/jinja2/plainui/profile.html b/src/plainui/jinja2/plainui/profile.html index 98ca645030fd8292e1c13ee0f1aad5fc8f326205..a3600048efef2a96cad50f75c6ebe25299364b9a 100644 --- a/src/plainui/jinja2/plainui/profile.html +++ b/src/plainui/jinja2/plainui/profile.html @@ -63,47 +63,37 @@ </div> </form> </div> -<hr class="rc3-spacer"> +<hr class="rc3-spacer" id="badges"> <div class="row border m-0 my-5 p-0 bg-opaque"> <h2 class="bg-white text-center text-dark m-0 px-3 py-1 w-100">{{ _("My Badges") }}</h2> - <div class="p-3 container-fluid content-row"> - - <div class="row m-0 mb-3"> - <form method="POST" class="horizontal" action="{{ url('plainui:redeem_badge') }}"> - {{ csrf_input }} - <div class="form-row align-items-start fw-normal"> - <div class="col-12"> - <h3 class="font-sans-serif m-1 m-0">{{ _("Redeem Token") }}</h3> - </div> - <div class="col-12"> - <input name="token" class="form-control mb-2" placeholder="Token" > - </div> - <div class="col-3"> - <input type="submit" class="btn btn-primary mb-2"> - </div> - </div> - </form> - </div> + <div class="p-3"> - <div class="m-0 mb-3"> - <h3 class="font-sans-serif m-1 m-0">{{ _("Manage Badges") }}</h3> - {% if amount_badges_not_accepted > 0 %} - {{ _("Pending badges") }}: {{ amount_badges_not_accepted }}<br> - {% endif %} - <a class="a a-bold" href="{{ url('plainui:manage_badges') }}"> + <h2 class="font-sans-serif m-1 m-0">{{ _("Manage Badges") }}</h2> + {% if amount_badges_not_accepted > 0 %} + <p class="">{{ _("Pending badges") }}: <a class="a a-bold" href="{{ url('plainui:manage_badges') }}"> + {{ amount_badges_not_accepted }}</a></p> + {% endif %} + <form method="POST" class="horizontal" action="{{ url('plainui:redeem_badge') }}"> + {{ csrf_input }} + <input name="token" class="form-control mb-2" placeholder="Token" > + <input type="submit" class="btn btn-primary mb-2" value="{{ _('Redeem') }}"> + </form> + + <p class="mb-2"> + <a class="a a-bold" href="{{ url('plainui:manage_badges') }}"> {{ _("Badges: Accept / Revoke / Visibility") }} - </a><br /> + </a> + <br /> <a href="/api/badges.zip" class="a a-bold"> {{ _("Export Your Badges") }} </a> - </div> - + </p> - <div class="row m-0"> + <div class="badges-gallery m-0"> {% if not badges %} - <div class="row my-5 p-6"> + <div class="my-5 p-6"> {{ _("No entries available.") }} </div> {% endif %} diff --git a/src/plainui/jinja2/plainui/user.html b/src/plainui/jinja2/plainui/user.html index ff8aa8195bbcf09f187783e0356117e736040483..837fb1603171c04e131e5e758cf7af3723eabd7e 100644 --- a/src/plainui/jinja2/plainui/user.html +++ b/src/plainui/jinja2/plainui/user.html @@ -76,9 +76,9 @@ <div class="border my-8 p-0 bg-opaque"> <h2 class="bg-white text-center text-dark m-0 px-3 py-1">{{ _("badges") }}</h2> - <div class="row m-0 p-3"> + <div class="badges-gallery m-0 p-3"> {% if not badges %} - <div class="row my-5 p-6"> + <div class="my-5 p-6"> {{ _("No entries available.") }} </div> {% endif %} diff --git a/src/plainui/locale/de/LC_MESSAGES/django.po b/src/plainui/locale/de/LC_MESSAGES/django.po index 237ee6ad5a35e2f61a808218372cc47bd292c5d6..bf877ff2176df217ae4b2d2250dcfb870652f7c7 100644 --- a/src/plainui/locale/de/LC_MESSAGES/django.po +++ b/src/plainui/locale/de/LC_MESSAGES/django.po @@ -545,7 +545,7 @@ msgid "My Badges" msgstr "Meine Badges" msgid "Manage Badges" -msgstr "Badgeverwaltung" +msgstr "Badge-Verwaltung" msgid "Pending badges" msgstr "Ausstehende Badges" @@ -554,7 +554,7 @@ msgid "Badges: Accept / Revoke / Visibility" msgstr "Badges: Akzeptieren / Widerrufen / Sichtbarkeit" msgid "Export Your Badges" -msgstr "Exportiere alle deine Badges als ZIP-Datei." +msgstr "Exportiere alle deine Badges als ZIP-Datei" msgid "My Favorites" msgstr "Meine Favoriten" @@ -841,6 +841,9 @@ msgstr "" msgid "Redeem Badge Token" msgstr "Redeem Badge Token" +msgid "Redeem" +msgstr "Einlösen" + #, python-format msgid "Conference %(conf)s - Redeem Token" msgstr "Veranstaltung %(conf)s - Token einlösen" diff --git a/src/plainui/styles/_util-classes.scss b/src/plainui/styles/_util-classes.scss index bff7486e62fc7ea357aa7124d7667f159efc7637..1baabaebac7e126ec55fcc83797fb3c469969d6a 100644 --- a/src/plainui/styles/_util-classes.scss +++ b/src/plainui/styles/_util-classes.scss @@ -758,4 +758,9 @@ h6, background-image: url($icon-ani-4); } } -} \ No newline at end of file +} + +.aspect-ratio-16by9 { + aspect-ratio: 1; + object-fit: contain; +} diff --git a/src/plainui/styles/components/_badges.scss b/src/plainui/styles/components/_badges.scss new file mode 100644 index 0000000000000000000000000000000000000000..79628a37da9629c3d7896b1b7661d8e336ef8d74 --- /dev/null +++ b/src/plainui/styles/components/_badges.scss @@ -0,0 +1,17 @@ +.badges-gallery { + display: grid; + gap: 1rem; + grid-template-columns: 1fr; + + @include media-breakpoint-up("md") { + grid-template-columns: 1fr 1fr; + } + + @include media-breakpoint-up("lg") { + grid-template-columns: 1fr 1fr 1fr; + } + + @include media-breakpoint-up("xl") { + grid-template-columns: 1fr 1fr 1fr 1fr; + } +} diff --git a/src/plainui/styles/components/_index.scss b/src/plainui/styles/components/_index.scss index 69df99d6f35345dcdfad2d33c7551b77cbc79a1b..6da9d57fde699dad7785419ac9be9bb4040c29d4 100644 --- a/src/plainui/styles/components/_index.scss +++ b/src/plainui/styles/components/_index.scss @@ -12,3 +12,4 @@ @import "slider"; @import "image"; @import "avatar"; +@import "badges";