From e641ade1b249c2e8ffb083c91e95a36f128f9afe Mon Sep 17 00:00:00 2001 From: Nikola Kubeczkova Date: Mon, 7 Apr 2025 21:51:22 +0200 Subject: [PATCH] fix gallery and menu --- services/backend/tko/serializers.py | 11 +- services/frontend/assets/css/main.css | 49 ++++++++- services/frontend/components/About.vue | 4 +- services/frontend/components/Courses.vue | 27 +++-- services/frontend/components/News.vue | 78 ++++++------- services/frontend/components/Trainers.vue | 19 ++-- .../frontend/components/dialog/Carousel.vue | 25 +++-- services/frontend/components/menu/Header.vue | 104 ++++++++++++++---- services/frontend/composables/useGoTo.ts | 41 ++++--- services/frontend/pages/galerie.vue | 49 +++++---- services/frontend/plugins/vuetify.ts | 4 + 11 files changed, 275 insertions(+), 136 deletions(-) diff --git a/services/backend/tko/serializers.py b/services/backend/tko/serializers.py index 389d103..b551ad8 100644 --- a/services/backend/tko/serializers.py +++ b/services/backend/tko/serializers.py @@ -35,11 +35,14 @@ class ArticleListSerializer(serializers.ModelSerializer): def get_date(obj): return obj.date.strftime("%-d. %-m. %Y") - @staticmethod - def get_image(obj): + def get_image(self, obj): main_image = obj.images.order_by("main").first() - url = 'http://localhost:8000' - return f"{url}{main_image.image.url}" if main_image else None + if main_image: + return ArticleImageSerializer(main_image, context=self.context).data + return { + "image": "http://localhost:8000/media/images/image.jpg", + "title": "Výchozí obrázek", + } class EventListSerializer(serializers.ModelSerializer): diff --git a/services/frontend/assets/css/main.css b/services/frontend/assets/css/main.css index 2fd442c..95f0baf 100644 --- a/services/frontend/assets/css/main.css +++ b/services/frontend/assets/css/main.css @@ -12,6 +12,7 @@ h1 { margin-bottom: 1rem; margin-top: 2rem; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); + cursor: default; } h2 { @@ -20,6 +21,7 @@ h2 { text-align: center; word-break: break-word; margin-bottom: 2rem; + cursor: default; } h3 { @@ -27,6 +29,7 @@ h3 { color: #666; text-align: center; margin-bottom: 0.5rem; + cursor: default; } h4 { @@ -34,12 +37,14 @@ h4 { color: #666; text-align: center; margin-bottom: 0.5rem; + cursor: default; } h5 { font-size: 1rem; color: #aaa; margin-top: 1rem; + cursor: default; } @media (max-width: 600px) { @@ -68,6 +73,7 @@ h5 { .app__title { font-size: 2rem; color: #333; + cursor: default; } .app__tab { @@ -95,6 +101,7 @@ h5 { color: #333; margin-bottom: 1rem; font-weight: bold; + cursor: default; } .contact__dialog__title { @@ -102,6 +109,8 @@ h5 { color: #333; margin-bottom: 1rem; font-weight: bold; + word-break: break-word !important; + cursor: default; } .contact__button { @@ -116,7 +125,6 @@ h5 { } .contact { - min-width: unset; margin: 10px; padding: 1rem; } @@ -130,6 +138,7 @@ h5 { .contact__dialog__title { font-size: 1.5rem; margin-bottom: 0.5rem; + word-break: break-word; } } @@ -138,6 +147,7 @@ h5 { justify-content: center; margin: 0 auto; max-width: 1200px; + cursor: default; } .article { @@ -146,17 +156,20 @@ h5 { border-radius: 0; box-shadow: 0 0 0 rgba(0, 0, 0, 0); margin-bottom: 1rem; + cursor: default; } .article__title { font-size: 1.4rem; color: #CF3476; font-weight: bold; + cursor: default; } .article__date { font-size: 0.8rem; text-align: left; + cursor: default; } .article__text { @@ -165,6 +178,11 @@ h5 { line-height: 1.5; padding: 0.5rem; margin-bottom: 1rem; + cursor: default; +} + +.article__image:hover { + cursor: pointer; } .article__sign { @@ -172,6 +190,7 @@ h5 { font-size: 1rem; font-style: italic; color: #555; + cursor: default; } .show_more { @@ -222,6 +241,7 @@ h5 { .pricing-title { min-height: 3rem; + cursor: pointer; } .pricing-desc { @@ -274,6 +294,7 @@ h5 { height: 100%; text-align: center; padding: 2rem; + cursor: default; } .trainer-avatar { @@ -310,6 +331,7 @@ h5 { margin-top: 1.2rem; margin-left: calc(20% - 2.5rem); margin-right: calc(20% - 2.5rem); + cursor: default; } .advantage__title { @@ -318,12 +340,14 @@ h5 { font-size: 1.5rem; font-weight: bold; margin-top: 0.1rem; + cursor: default; } .advantage__text { padding-bottom: 1rem; font-size: 1rem; color: #333; + cursor: default; } @media (max-width: 600px) { @@ -352,6 +376,7 @@ h5 { margin: 0 auto; text-align: center; padding: 2rem; + cursor: default; } .about__parallax { @@ -377,6 +402,8 @@ h5 { font-weight: bold; word-break: break-word; white-space: normal; + display: block; + cursor: default; } .about__subtitle { @@ -385,6 +412,8 @@ h5 { margin-bottom: 1rem; word-break: break-word; font-weight: bold; + display: block; + cursor: default; } .about__text { @@ -392,6 +421,7 @@ h5 { font-size: 1.125rem; padding: 0 1rem; line-height: 1.6; + cursor: default; } @media (max-width: 600px) { @@ -418,6 +448,23 @@ h5 { } } +.masonry-gallery { + columns: 3; + column-gap: 16px; +} + +@media (max-width: 600px) { + .masonry-gallery { + columns: 1; + } +} + +.masonry-item { + break-inside: avoid; + margin-bottom: 16px; +} + .footer { background-color: black; + cursor: default; } \ No newline at end of file diff --git a/services/frontend/components/About.vue b/services/frontend/components/About.vue index d250128..05118f4 100644 --- a/services/frontend/components/About.vue +++ b/services/frontend/components/About.vue @@ -4,8 +4,8 @@ src="public/dark-dance.jpg" scale="0.8" > - - + + Vítejte v tanečním klubu! Objevte kouzlo tance s námi! diff --git a/services/frontend/components/Courses.vue b/services/frontend/components/Courses.vue index e396eb7..42682e2 100644 --- a/services/frontend/components/Courses.vue +++ b/services/frontend/components/Courses.vue @@ -38,29 +38,28 @@ transition="dialog-bottom-transition" > - +

{{ chosenCourse.name }} - +

+ +
{{ chosenCourse.desc }}
+
- -
{{ chosenCourse.desc }}
-
- - + Kontaktujte nás! - -
- - + +
+ + - - - + + + \ No newline at end of file diff --git a/services/frontend/components/Trainers.vue b/services/frontend/components/Trainers.vue index 60dcd32..046b82b 100644 --- a/services/frontend/components/Trainers.vue +++ b/services/frontend/components/Trainers.vue @@ -1,11 +1,11 @@ \ No newline at end of file diff --git a/services/frontend/composables/useGoTo.ts b/services/frontend/composables/useGoTo.ts index f287af3..926cbfe 100644 --- a/services/frontend/composables/useGoTo.ts +++ b/services/frontend/composables/useGoTo.ts @@ -7,30 +7,35 @@ export async function useGoTo( ): Promise { const router = useRouter(); const route = useRoute(); - const yOffset = props?.offset ?? -80; + const yOffset = props?.offset ?? -150; const hash = selector.startsWith("#") ? selector : ""; - const path = selector.startsWith("/") ? selector : route.path + hash; + const basePath = route.path.split("#")[0]; + const targetPath = selector.startsWith("/") ? selector : basePath + hash; + const [pathOnly, hashOnly] = targetPath.split("#"); - // If navigating to another page - if (route.path !== path.split("#")[0]) { - await router.push(path); - await nextTick(); // Ensure DOM updates + if (route.path !== pathOnly) { + // Navigate to target page + await router.push(pathOnly + (hashOnly ? `#${hashOnly}` : "")); + await nextTick(); - // Wait for the element to exist before scrolling - try { - const element = await waitForElement(hash); - scrollToElement(element, yOffset); - } catch (error) { - console.warn(error); + if (hashOnly) { + try { + const element = await waitForElement(`#${hashOnly}`); + scrollToElement(element, yOffset); + } catch (err) { + console.warn(err); + } } } else { - // If already on the correct page, scroll immediately - try { - const element = await waitForElement(hash); - scrollToElement(element, yOffset); - } catch (error) { - console.warn(error); + // Same page — scroll directly + if (hashOnly || selector.startsWith("#")) { + try { + const element = await waitForElement(`#${hashOnly ?? selector}`); + scrollToElement(element, yOffset); + } catch (err) { + console.warn(err); + } } } } diff --git a/services/frontend/pages/galerie.vue b/services/frontend/pages/galerie.vue index 64f5de5..264a852 100644 --- a/services/frontend/pages/galerie.vue +++ b/services/frontend/pages/galerie.vue @@ -1,44 +1,47 @@