diff --git a/backend/samfundet/migrations/0001_initial.py b/backend/samfundet/migrations/0001_initial.py index 0ea8f1fdf..5ecee6c5e 100644 --- a/backend/samfundet/migrations/0001_initial.py +++ b/backend/samfundet/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.9 on 2025-08-09 16:11 +# Generated by Django 5.2.10 on 2026-01-20 20:45 import datetime import django.contrib.auth.models @@ -138,8 +138,6 @@ class Migration(migrations.Migration): ('updated_at', models.DateTimeField(blank=True, editable=False, null=True)), ('message_nb', models.TextField(blank=True, null=True, verbose_name='Melding (norsk)')), ('message_en', models.TextField(blank=True, null=True, verbose_name='Melding (engelsk)')), - ('description_nb', models.TextField(blank=True, null=True, verbose_name='Beskrivelse (norsk)')), - ('description_en', models.TextField(blank=True, null=True, verbose_name='Beskrivelse (engelsk)')), ('start_dt', models.DateField(blank=True, verbose_name='Start dato')), ('end_dt', models.DateField(blank=True, verbose_name='Slutt dato')), ('created_by', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), diff --git a/backend/samfundet/migrations/0006_userpreference_closed_override.py b/backend/samfundet/migrations/0006_userpreference_closed_override.py new file mode 100644 index 000000000..d179a28a4 --- /dev/null +++ b/backend/samfundet/migrations/0006_userpreference_closed_override.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.10 on 2026-03-10 11:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('samfundet', '0005_medlemsinfo'), + ] + + operations = [ + migrations.AddField( + model_name='userpreference', + name='closed_override', + field=models.CharField(default='default', max_length=30), + ), + ] diff --git a/backend/samfundet/migrations/0007_alter_userpreference_closed_override.py b/backend/samfundet/migrations/0007_alter_userpreference_closed_override.py new file mode 100644 index 000000000..a9afe3411 --- /dev/null +++ b/backend/samfundet/migrations/0007_alter_userpreference_closed_override.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.11 on 2026-04-09 17:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('samfundet', '0006_userpreference_closed_override'), + ] + + operations = [ + migrations.AlterField( + model_name='userpreference', + name='closed_override', + field=models.CharField(choices=[('default', 'Default'), ('closed', 'Closed'), ('open', 'Open')], default='default', max_length=30), + ), + ] diff --git a/backend/samfundet/migrations/0008_remove_userpreference_closed_override.py b/backend/samfundet/migrations/0008_remove_userpreference_closed_override.py new file mode 100644 index 000000000..0bd66143c --- /dev/null +++ b/backend/samfundet/migrations/0008_remove_userpreference_closed_override.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.11 on 2026-04-14 19:59 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('samfundet', '0007_alter_userpreference_closed_override'), + ] + + operations = [ + migrations.RemoveField( + model_name='userpreference', + name='closed_override', + ), + ] diff --git a/backend/samfundet/models/general.py b/backend/samfundet/models/general.py index 073b212da..6575a574a 100644 --- a/backend/samfundet/models/general.py +++ b/backend/samfundet/models/general.py @@ -260,9 +260,6 @@ class ClosedPeriod(CustomBaseModel): message_nb = models.TextField(blank=True, null=True, verbose_name='Melding (norsk)') message_en = models.TextField(blank=True, null=True, verbose_name='Melding (engelsk)') - description_nb = models.TextField(blank=True, null=True, verbose_name='Beskrivelse (norsk)') - description_en = models.TextField(blank=True, null=True, verbose_name='Beskrivelse (engelsk)') - start_dt = models.DateField(blank=True, null=False, verbose_name='Start dato') end_dt = models.DateField(blank=True, null=False, verbose_name='Slutt dato') diff --git a/frontend/src/Components/OpeningHours/OpeningHours.module.scss b/frontend/src/Components/OpeningHours/OpeningHours.module.scss index 25bf61013..f0ad13a49 100644 --- a/frontend/src/Components/OpeningHours/OpeningHours.module.scss +++ b/frontend/src/Components/OpeningHours/OpeningHours.module.scss @@ -10,8 +10,8 @@ align-items: center; @include theme-dark { - background-color: $black-2; - color: $white; + background-color: $theme-dark-bg; + color: $theme-dark-color; } } @@ -26,3 +26,10 @@ margin: 0 0.2em; } +.closedBox { + border: 2px $red_samf solid; + border-radius: 10px; + padding: 20px; + margin-bottom: 2rem; + margin-top: 1rem; +} diff --git a/frontend/src/Components/OpeningHours/OpeningHours.tsx b/frontend/src/Components/OpeningHours/OpeningHours.tsx index 6c4e9b57e..4004894c5 100644 --- a/frontend/src/Components/OpeningHours/OpeningHours.tsx +++ b/frontend/src/Components/OpeningHours/OpeningHours.tsx @@ -1,9 +1,13 @@ +import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { toast } from 'react-toastify'; import { TimeDuration } from '~/Components'; import { Link } from '~/Components/Link/Link'; import { Text } from '~/Components/Text/Text'; +import { getActiveClosedPeriods } from '~/api'; import type { VenueDto } from '~/dto'; import { KEY } from '~/i18n/constants'; +import { dbT } from '~/utils'; import styles from './OpeningHours.module.scss'; type OpeningHoursProps = { @@ -14,6 +18,23 @@ type OpeningHoursProps = { export function OpeningHours({ venues, isLoading, isError }: OpeningHoursProps) { const { t } = useTranslation(); + const [isClosed, setIsClosed] = useState(false); + const [closedText, setClosedText] = useState(undefined); + + useEffect(() => { + getActiveClosedPeriods() + .then((periods) => { + if (periods.length !== 0) { + setIsClosed(true); + setClosedText(dbT(periods[0], 'message')); + return; + } + }) + .catch((error) => { + toast.error(t(KEY.common_something_went_wrong)); + console.error(error); + }); + }, [t]); if (isLoading) { return {t(KEY.common_loading)}; @@ -25,34 +46,37 @@ export function OpeningHours({ venues, isLoading, isError }: OpeningHoursProps) const today = new Date().toISOString().split('T')[0]; const day = new Date().toLocaleDateString('en-US', { weekday: 'long' }).toLowerCase(); - return (
{t(KEY.common_opening_hours)} - - {venues.map((venue) => { - const openingTime = venue[`opening_${day}` as keyof VenueDto] as string; - const closingTime = venue[`closing_${day}` as keyof VenueDto] as string; - return ( - - - - - ); - })} -
- -

{venue.name}

- -
- -
+ {isClosed ? ( +
{closedText}
+ ) : ( + + {venues.map((venue) => { + const openingTime = venue[`opening_${day}` as keyof VenueDto] as string; + const closingTime = venue[`closing_${day}` as keyof VenueDto] as string; + return ( + + + + + ); + })} +
+ +

{venue.name}

+ +
+ +
+ )}
); } diff --git a/frontend/src/Components/OpeningHours/index.ts b/frontend/src/Components/OpeningHours/index.ts index beb1448d2..37a62d505 100644 --- a/frontend/src/Components/OpeningHours/index.ts +++ b/frontend/src/Components/OpeningHours/index.ts @@ -1 +1,2 @@ export { OpeningHours } from './OpeningHours'; +export { OpeningHoursContainer } from './OpeningHoursContainer'; diff --git a/frontend/src/Components/Page/Page.module.scss b/frontend/src/Components/Page/Page.module.scss index b388b279c..932619c89 100644 --- a/frontend/src/Components/Page/Page.module.scss +++ b/frontend/src/Components/Page/Page.module.scss @@ -14,8 +14,6 @@ $side-padding: 1em; // Limit max content size for large screens. max-width: $content-max-size; - - // Center all content. margin: auto; @include for-mobile-only { diff --git a/frontend/src/Components/index.ts b/frontend/src/Components/index.ts index 1ffd6c92e..8fef60473 100644 --- a/frontend/src/Components/index.ts +++ b/frontend/src/Components/index.ts @@ -51,7 +51,7 @@ export { Navbar } from './Navbar'; export { NotificationBadge } from './NotificationBadge'; export { NumberInput } from './NumberInput'; export { OccupiedForm, OccupiedFormModal } from './OccupiedForm'; -export { OpeningHours } from './OpeningHours'; +export { OpeningHours, OpeningHoursContainer } from './OpeningHours'; export { Page } from './Page'; export { PagedPagination } from './Pagination'; export { PermissionRoute } from './PermissionRoute'; diff --git a/frontend/src/Pages/HomePage/HomePage.tsx b/frontend/src/Pages/HomePage/HomePage.tsx index 7e14ecc40..74d88c513 100644 --- a/frontend/src/Pages/HomePage/HomePage.tsx +++ b/frontend/src/Pages/HomePage/HomePage.tsx @@ -1,6 +1,7 @@ import { type ReactNode, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { toast } from 'react-toastify'; +import { OpeningHoursContainer } from '~/Components'; import { EventCarousel, LargeCard } from '~/Pages/HomePage/components'; import { getHomeData } from '~/api'; import type { HomePageDto, HomePageElementDto } from '~/dto'; @@ -50,6 +51,7 @@ export function HomePage() { return ( <> +
{/**/} {isLoading && skeleton} diff --git a/frontend/src/PagesAdmin/AdminPageLayout/AdminPageLayout.module.scss b/frontend/src/PagesAdmin/AdminPageLayout/AdminPageLayout.module.scss index 92b3009ab..eb91dd4b8 100644 --- a/frontend/src/PagesAdmin/AdminPageLayout/AdminPageLayout.module.scss +++ b/frontend/src/PagesAdmin/AdminPageLayout/AdminPageLayout.module.scss @@ -36,6 +36,7 @@ $header-bg-dark: #111111; flex-direction: row; padding-bottom: 1.5em; gap: 1em; + align-items: center; } .spinner_container { diff --git a/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.module.scss b/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.module.scss index 2a8635da1..b1d85eb72 100644 --- a/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.module.scss +++ b/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.module.scss @@ -1,3 +1,9 @@ @use 'src/mixins' as *; @use 'src/constants' as *; + +.edit_buttons { + display: flex; + flex-direction: column; + gap: 5px; +} diff --git a/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.tsx b/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.tsx index 9c20e233b..f77095887 100644 --- a/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.tsx +++ b/frontend/src/PagesAdmin/ClosedPeriodAdminPage/ClosedPeriodAdminPage.tsx @@ -51,9 +51,11 @@ export function ClosedPeriodAdminPage() { } const header = ( - + <> + + ); const backendUrl = ROUTES.backend.admin__samfundet_closedperiod_changelist; @@ -67,21 +69,21 @@ export function ClosedPeriodAdminPage() {
({ cells: [ - element.message_no, - element.description_no, + element.message_nb, + element.message_en, { content: }, { content: }, { content: ( -
+