diff --git a/README.md b/README.md index d841b5b..61f65e1 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@ ## Running -1. `docker compose run --rm frontend npm install` -2. `docker compose build` -3. `docker compose up` +1. create .env from .env.example +2. `docker compose run --rm frontend npm install` +3. `docker compose build` +4. `docker compose up` ## Adding new frontend packages diff --git a/services/backend/backend/urls.py b/services/backend/backend/urls.py index 0e29a78..460ef43 100644 --- a/services/backend/backend/urls.py +++ b/services/backend/backend/urls.py @@ -21,7 +21,7 @@ from debug_toolbar.toolbar import debug_toolbar_urls from django.conf.urls.static import static from django.conf import settings -from tko.views import ContactView, NewArticleListView, AllArticleListView, EventListView +from tko.views import ContactView, NewArticleListView, AllArticleListView, EventListView, GalleryView urlpatterns = [ path('admin/', admin.site.urls), @@ -29,6 +29,7 @@ urlpatterns = [ path('load-articles/', NewArticleListView.as_view(), name='load-articles'), path('load-all-articles/', AllArticleListView.as_view(), name='load-all-articles'), path('load-events/', EventListView.as_view(), name='load-events'), + path('load-gallery/', GalleryView.as_view(), name='load-gallery'), ] + debug_toolbar_urls() urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/services/backend/tko/migrations/0006_remove_articleimage_is_main_article_image_and_more.py b/services/backend/tko/migrations/0006_remove_articleimage_is_main_article_image_and_more.py new file mode 100644 index 0000000..5b2207a --- /dev/null +++ b/services/backend/tko/migrations/0006_remove_articleimage_is_main_article_image_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.5 on 2025-03-10 16:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tko', '0005_remove_article_image_alter_article_date_articleimage'), + ] + + operations = [ + migrations.RemoveField( + model_name='articleimage', + name='is_main', + ), + migrations.AddField( + model_name='article', + name='image', + field=models.FileField(blank=True, default='default.png', upload_to='images/%Y'), + ), + migrations.AlterField( + model_name='articleimage', + name='image', + field=models.FileField(upload_to='images/%Y'), + ), + ] diff --git a/services/backend/tko/migrations/0007_remove_article_image_articleimage_main_and_more.py b/services/backend/tko/migrations/0007_remove_article_image_articleimage_main_and_more.py new file mode 100644 index 0000000..f1e8227 --- /dev/null +++ b/services/backend/tko/migrations/0007_remove_article_image_articleimage_main_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.5 on 2025-03-10 18:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tko', '0006_remove_articleimage_is_main_article_image_and_more'), + ] + + operations = [ + migrations.RemoveField( + model_name='article', + name='image', + ), + migrations.AddField( + model_name='articleimage', + name='main', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='articleimage', + name='image', + field=models.FileField(default='default.png', upload_to='images/%Y'), + ), + ] diff --git a/services/backend/tko/models.py b/services/backend/tko/models.py index 0ddd66a..dc5fbe2 100644 --- a/services/backend/tko/models.py +++ b/services/backend/tko/models.py @@ -14,10 +14,8 @@ class Contact(models.Model): class Article(models.Model): title = models.CharField(max_length=100) content = models.TextField() - image = models.FileField(upload_to="images/%Y", default="default.png", blank=True) date = models.DateField(auto_now_add=True) author = models.CharField(max_length=100) - active_to = models.DateField(null=True, blank=True) # do not show some invitation after this date def __str__(self): @@ -26,7 +24,8 @@ class Article(models.Model): class ArticleImage(models.Model): article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='images') - image = models.FileField(upload_to="images/%Y") + image = models.FileField(upload_to="images/%Y", default="default.png") + main = models.BooleanField(default=False) def __str__(self): return f"Image for {self.article.title}, {self.article.date}" diff --git a/services/backend/tko/serializers.py b/services/backend/tko/serializers.py index 79b75a3..101d0e6 100644 --- a/services/backend/tko/serializers.py +++ b/services/backend/tko/serializers.py @@ -11,13 +11,20 @@ class ContactSerializer(serializers.ModelSerializer): class ArticleImageSerializer(serializers.ModelSerializer): + title = serializers.SerializerMethodField(read_only=True) + class Meta: model = ArticleImage - fields = ['image'] + fields = ['image', 'title'] + + @staticmethod + def get_title(obj): + return obj.article.title class ArticleListSerializer(serializers.ModelSerializer): date = serializers.SerializerMethodField() + image = serializers.SerializerMethodField() images = ArticleImageSerializer(many=True, read_only=True) class Meta: @@ -28,6 +35,11 @@ class ArticleListSerializer(serializers.ModelSerializer): def get_date(obj): return obj.date.strftime("%-d. %-m. %Y") + @staticmethod + def get_image(obj): + main_image = obj.images.order_by("main").first() + return main_image.image.url if main_image else None + class EventListSerializer(serializers.ModelSerializer): start = serializers.SerializerMethodField() diff --git a/services/backend/tko/views.py b/services/backend/tko/views.py index 590c233..4c9eb1f 100644 --- a/services/backend/tko/views.py +++ b/services/backend/tko/views.py @@ -4,8 +4,8 @@ from django.db.models import Q from rest_framework.generics import ListAPIView, CreateAPIView from rest_framework import permissions -from tko.models import Article, Event -from tko.serializers import ArticleListSerializer, EventListSerializer, ContactSerializer +from tko.models import Article, Event, ArticleImage +from tko.serializers import ArticleListSerializer, EventListSerializer, ContactSerializer, ArticleImageSerializer class ContactView(CreateAPIView): @@ -33,6 +33,12 @@ class AllArticleListView(ListAPIView): ).order_by('-date') +class GalleryView(ListAPIView): + queryset = ArticleImage.objects.all().order_by("-article_id", "main") + serializer_class = ArticleImageSerializer + permission_classes = [permissions.AllowAny] + + class EventListView(ListAPIView): queryset = Event.objects.all() serializer_class = EventListSerializer diff --git a/services/frontend/assets/css/main.css b/services/frontend/assets/css/main.css index 139916a..87b6c72 100644 --- a/services/frontend/assets/css/main.css +++ b/services/frontend/assets/css/main.css @@ -118,6 +118,12 @@ h5 { border-radius: 0.5rem; } +.carousel__image img { + border-radius: 0.5rem; + object-fit: contain !important; + padding: 1rem; +} + .article__title { font-family: 'Futura', sans-serif; font-size: 1.5rem; diff --git a/services/frontend/components/News.vue b/services/frontend/components/News.vue index 0356e0c..c7a7553 100644 --- a/services/frontend/components/News.vue +++ b/services/frontend/components/News.vue @@ -12,20 +12,26 @@ + + + \ No newline at end of file diff --git a/services/frontend/components/dialog/Carousel.vue b/services/frontend/components/dialog/Carousel.vue new file mode 100644 index 0000000..751178d --- /dev/null +++ b/services/frontend/components/dialog/Carousel.vue @@ -0,0 +1,35 @@ + + + \ No newline at end of file diff --git a/services/frontend/pages/galerie.vue b/services/frontend/pages/galerie.vue index 90c7dbc..b35309b 100644 --- a/services/frontend/pages/galerie.vue +++ b/services/frontend/pages/galerie.vue @@ -2,16 +2,17 @@

Galerie

+ + + \ No newline at end of file