diff --git a/ClubSite/Assets/scss/inc/_blocks.scss b/ClubSite/Assets/scss/inc/_blocks.scss index f36839a..3d7c708 100644 --- a/ClubSite/Assets/scss/inc/_blocks.scss +++ b/ClubSite/Assets/scss/inc/_blocks.scss @@ -23,14 +23,27 @@ overflow: hidden; } } -} -// Medium devices (tablets, 768px and up) -@media (min-width: 768px) { - .block { - &.column-block { - .col-md:not(:last-child) { - margin-bottom: 0; + &.separator-block { + padding: 0 0 .5rem + } + + &.new-posts-block { + padding: 0; + margin: 0; + + article h3 { + font-size: 1.5rem !important; + } + } + + // Medium devices (tablets, 768px and up) + @media (min-width: 768px) { + .block { + &.column-block { + .col-md:not(:last-child) { + margin-bottom: 0; + } } } } diff --git a/ClubSite/Assets/scss/inc/_general.scss b/ClubSite/Assets/scss/inc/_general.scss index 53e2a42..9a9d1d0 100644 --- a/ClubSite/Assets/scss/inc/_general.scss +++ b/ClubSite/Assets/scss/inc/_general.scss @@ -5,8 +5,9 @@ } main { // needed for Post, Archive, Page - padding: 2rem 0; + padding: 1rem 0; } + img { max-width: 100%; } diff --git a/ClubSite/Assets/scss/inc/_pagination.scss b/ClubSite/Assets/scss/inc/_pagination.scss new file mode 100644 index 0000000..7d01df6 --- /dev/null +++ b/ClubSite/Assets/scss/inc/_pagination.scss @@ -0,0 +1,18 @@ +.page-link { + color: #f44336; + min-width: 2.5rem; + text-align: center; + + &:hover { + color: darken(#f44336, 10%); + } +} + +.page-item { + &.active { + .page-link { + background: #f44336; + border-color: #f44336; + } + } +} diff --git a/ClubSite/Assets/scss/style.scss b/ClubSite/Assets/scss/style.scss index 3b411f4..f604f59 100644 --- a/ClubSite/Assets/scss/style.scss +++ b/ClubSite/Assets/scss/style.scss @@ -8,3 +8,4 @@ @import "inc/header"; @import "inc/blocks"; @import "inc/posts"; +@import "inc/pagination"; diff --git a/ClubSite/ClubSite.csproj b/ClubSite/ClubSite.csproj index 7547e8f..fec6eaa 100644 --- a/ClubSite/ClubSite.csproj +++ b/ClubSite/ClubSite.csproj @@ -3,7 +3,7 @@ net6.0 enable - 3.1.0 + 3.2.0 axuno gGmbH The source code for https://www.volleyballclub.de/ axuno gGmbH and Contributors @@ -11,27 +11,28 @@ - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/ClubSite/ConfigurationPoco/MailSettings.cs b/ClubSite/ConfigurationPoco/MailSettings.cs index 150554c..0642960 100644 --- a/ClubSite/ConfigurationPoco/MailSettings.cs +++ b/ClubSite/ConfigurationPoco/MailSettings.cs @@ -3,19 +3,21 @@ // of the MIT license. See the LICENSE file for details. // https://github.com/axuno/ClubSite +using System; + namespace ClubSite.ConfigurationPoco { public class MailSettings { - public Sender Sender { get; set; } = new Sender(); - public Message Message { get; set; } = new Message(); + public Sender Sender { get; set; } = new (); + public Message Message { get; set; } = new (); } public class Sender { public string MessageOutput { get; set; } = string.Empty; - public Smtp Smtp { get; set; } = new Smtp(); - public File File { get; set; } = new File(); + public Smtp Smtp { get; set; } = new (); + public File File { get; set; } = new (); } public class Smtp @@ -35,7 +37,7 @@ public class File public class Message { public MailAddress DefaultFrom { get; set; } = new (); - public MailAddress[] ContactFormTo { get; set; } = { }; + public MailAddress[] ContactFormTo { get; set; } = Array.Empty(); public string? Organization { get; set; } } diff --git a/ClubSite/Models/ContactPage.cs b/ClubSite/Models/ContactPage.cs index 5189d07..2645b6e 100644 --- a/ClubSite/Models/ContactPage.cs +++ b/ClubSite/Models/ContactPage.cs @@ -3,10 +3,7 @@ // of the MIT license. See the LICENSE file for details. // https://github.com/axuno/ClubSite -using System.Collections.Generic; using Piranha.AttributeBuilder; -using Piranha.Extend; -using Piranha.Extend.Fields; using Piranha.Models; namespace ClubSite.Models diff --git a/ClubSite/Models/NewPostsBlock.cs b/ClubSite/Models/NewPostsBlock.cs new file mode 100644 index 0000000..eb3d7cc --- /dev/null +++ b/ClubSite/Models/NewPostsBlock.cs @@ -0,0 +1,54 @@ +// Copyright (C) axuno gGmbH and Contributors. +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// https://github.com/axuno/ClubSite + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Piranha; +using Piranha.Data; +using Piranha.Extend; +using Piranha.Extend.Fields; +using Piranha.Models; + +namespace ClubSite.Models +{ + [BlockType(Name = "Latest Posts", Category = "References", Icon = "fas fa-link")] + public class NewPostsBlock : Piranha.Extend.Block + { + private const int NumOfDays = 30; + private const int MaxPosts = 2; + + [Field(Title = "Überschrift")] + public StringField Title { get; set; } = new() { Value = string.Empty }; + + [Field(Title = "Tage seit letztem Beitrag", Description = "In diesem Zeitraum werden Beiträge als \"aktuell\" behandelt.")] + public NumberField NumOfDaysSincePublication { get; set; } = new() { Value = NumOfDays }; + + [Field(Title = "Max. Anzahl der angezeigten Beiträge", Description = "Empfohlen: 2. Werte kleiner 1 unterdrücken die Ausgabe")] + public NumberField NumOfPostsToDisplay { get; set; } = new() { Value = MaxPosts }; + + public List Posts { get; private set; } = new(); + + public PageInfo ArchivePage { get; set; } = new(); + public async Task Init(IDb db, IApi api) + { + var blogId = db.Set().First(p => p.PageTypeId == nameof(StandardArchive)).Id; + // PageInfo will exclude all regions and blocks from the model, which we don't need here + ArchivePage = await api.Pages.GetByIdAsync(blogId); + + if(NumOfPostsToDisplay < 1) return; + var postArchive = await api.Archives.GetByIdAsync(blogId); + + // Returns only posts that have IsPublished true, while api.Posts.GetAllAsync gets ALL + var posts = postArchive.Posts.Take(NumOfPostsToDisplay.Value ?? 0).ToList(); + if (posts.Any() + && posts.First().Published >= DateTime.Now.Date.AddDays(-1 * NumOfDaysSincePublication.Value ?? 0)) + { + Posts = posts; + } + } + } +} \ No newline at end of file diff --git a/ClubSite/Models/PersonProfileBlock.cs b/ClubSite/Models/PersonProfileBlock.cs index 83b4810..9dd4eff 100644 --- a/ClubSite/Models/PersonProfileBlock.cs +++ b/ClubSite/Models/PersonProfileBlock.cs @@ -3,23 +3,24 @@ // of the MIT license. See the LICENSE file for details. // https://github.com/axuno/ClubSite -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using Piranha.Extend; -using Piranha.Extend.Blocks; using Piranha.Extend.Fields; +using Piranha.Extend.Fields.Settings; using Piranha.Models; namespace ClubSite.Models { - [BlockGroupType(Name = "Person Profile", Category = "Content", Icon = "fas fa-images", - Display = BlockDisplayMode.Horizontal)] - [BlockItemType(Type = typeof(ImageBlock))] - [BlockItemType(Type = typeof(HtmlBlock))] - public class PersonProfileBlock : BlockGroup + [BlockType(Name = "Person Profile", Category = "Content", Icon = "fas fa-user")] + public class PersonProfileBlock : Block { - public StringField Title { get; set; } = new StringField(); + [Field(Title = "Funktionsbezeichnung")] + [StringFieldSettings(MaxLength = 40)] + public StringField Title { get; set; } = new(); + + [Field(Title = "Name, Kontaktdaten", Options = FieldOption.HalfWidth)] + public HtmlField? Contact { get; set; } + + [Field(Title = "Foto", Options = FieldOption.HalfWidth)] + public ImageField? Photo { get; set; } } } \ No newline at end of file diff --git a/ClubSite/Models/TournamentDefinition.cs b/ClubSite/Models/TournamentDefinition.cs new file mode 100644 index 0000000..ea25f51 --- /dev/null +++ b/ClubSite/Models/TournamentDefinition.cs @@ -0,0 +1,77 @@ +// Copyright (C) axuno gGmbH and Contributors. +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. +// https://github.com/axuno/ClubSite + +using System; +using Piranha.Extend; +using Piranha.Extend.Fields; + +namespace ClubSite.Models; + +public class TournamentDefinition +{ + [Field(Title = "Primäres Bild", Placeholder = "Bild einsetzen")] + public ImageField TopImage { get; set; } = new(); + + [Field(Title = "Turniername", Placeholder = "z.B. 28. Neusäßer Mixedturnier")] + public StringField Name { get; set; } = new(); + + [Field(Title = "Datum von", Placeholder = "Datum")] + public DateField DateFrom { get; set; } = new(); + + [Field(Title = "Datum bis", Placeholder = "Datum")] + public DateField DateTo { get; set; } = new(); + + [Field(Title = "Uhrzeit von/bis", Placeholder = "Uhrzeit")] + public StringField TimeFromTo { get; set; } = new(); + + [Field(Title = "Beginn der Anmeldefrist", Placeholder = "Datum")] + public DateField RegistrationStart { get; set; } = new(); + + [Field(Title = "Anmeldeschluss", Placeholder = "Datum")] + public DateField RegistrationDeadline { get; set; } = new(); + + [Field(Title = "Anzahl Teams", Placeholder = "Anzahl")] + public NumberField NumberOfTeams { get; set; } = new(); + + [Field(Title = "Team-Zusammensetzung", Placeholder = "z.B. Anzahl Damen/Herren")] + public StringField TeamComposition { get; set; } = new(); + + [Field(Title = "Startgeld", Placeholder = "Startgeld")] + public StringField EntryFee { get; set; } = new(); + + [Field(Title = "Bankverbindung")] + public TextField BankDetails { get; set; } = new(); + + [Field(Title = "Adresse", Placeholder = "Hallenadresse")] + public StringField Address { get; set; } = new(); + + [Field(Title = "Infos", Placeholder = "Ablauf, Regeln, Infos")] + public HtmlField Infos { get; set; } = new(); + + public bool IsOver(DateTime dateToTest) + { + return DateFrom.Value == null + || DateTo.Value == null + || (DateFrom.Value.HasValue && + DateTo.Value.HasValue && + DateOnly.FromDateTime(DateTo.Value.Value) <= + DateOnly.FromDateTime(dateToTest)); + } + + public bool IsRegistrationAllowed(DateTime dateToTest) + { + return DateFrom.Value != null + && DateTo.Value != null + && RegistrationStart.Value.HasValue + && RegistrationDeadline.Value.HasValue + && dateToTest.Date >= RegistrationStart.Value.Value.Date + && dateToTest.Date <= RegistrationDeadline.Value.Value.Date; + } + + public bool IsRegistrationPeriodSet() + { + return RegistrationStart.Value.HasValue && RegistrationDeadline.Value.HasValue; + } +} \ No newline at end of file diff --git a/ClubSite/Models/TournamentPage.cs b/ClubSite/Models/TournamentPage.cs index 4798d1e..925081b 100644 --- a/ClubSite/Models/TournamentPage.cs +++ b/ClubSite/Models/TournamentPage.cs @@ -5,8 +5,6 @@ using Piranha.AttributeBuilder; using Piranha.Extend; -using Piranha.Extend.Blocks; -using Piranha.Extend.Fields; using Piranha.Models; namespace ClubSite.Models @@ -20,48 +18,6 @@ namespace ClubSite.Models public class TournamentPage : Page { [Region(Title = "Turnierbeschreibung", Description = "Festlegung der Eckdaten des Turniers")] - public TournamentDefinition TournamentDefinition { get; set; } = new TournamentDefinition(); - } - - public class TournamentDefinition - { - [Field(Title = "Primäres Bild", Placeholder = "Bild einsetzen")] - public ImageField TopImage { get; set; } = new ImageField(); - - [Field(Title = "Turniername", Placeholder = "z.B. 28. Neusäßer Mixedturnier")] - public StringField Name { get; set; } = new StringField(); - - [Field(Title = "Datum von", Placeholder = "Datum")] - public DateField DateFrom { get; set; } = new DateField(); - - [Field(Title = "Datum bis", Placeholder = "Datum")] - public DateField DateTo { get; set; } = new DateField(); - - [Field(Title = "Uhrzeit von/bis", Placeholder = "Uhrzeit")] - public StringField TimeFromTo { get; set; } = new StringField(); - - [Field(Title = "Beginn der Anmeldefrist", Placeholder = "Datum")] - public DateField RegistrationStart { get; set; } = new DateField(); - - [Field(Title = "Anmeldeschluss", Placeholder = "Datum")] - public DateField RegistrationDeadline { get; set; } = new DateField(); - - [Field(Title = "Anzahl Teams", Placeholder = "Anzahl")] - public NumberField NumberOfTeams { get; set; } = new NumberField(); - - [Field(Title = "Team-Zusammensetzung", Placeholder = "z.B. Anzahl Damen/Herren")] - public StringField TeamComposition { get; set; } = new StringField(); - - [Field(Title = "Startgeld", Placeholder = "Startgeld")] - public StringField EntryFee { get; set; } = new StringField(); - - [Field(Title = "Bankverbindung")] - public TextField BankDetails { get; set; } = new TextField(); - - [Field(Title = "Adresse", Placeholder = "Hallenadresse")] - public StringField Address { get; set; } = new StringField(); - - [Field(Title = "Infos", Placeholder = "Ablauf, Regeln, Infos")] - public HtmlField Infos { get; set; } = new HtmlField(); + public TournamentDefinition TournamentDefinition { get; set; } = new(); } } \ No newline at end of file diff --git a/ClubSite/Pages/Archive.cshtml b/ClubSite/Pages/Archive.cshtml index 6e16e93..da35a71 100644 --- a/ClubSite/Pages/Archive.cshtml +++ b/ClubSite/Pages/Archive.cshtml @@ -1,65 +1,40 @@ @page @model ArchivePage -@{ ViewData["Title"] = Model.Data.Title; - var hasImage = Model.Data.PrimaryImage.HasValue; - - var posts = Model.Archive.Posts.Count; +@{ + Model.ViewData["Title"] = Model.Data.Title; + var archiveInfo = await WebApp.Api.Pages.GetByIdAsync(Model.Data.Id); + + var showAll = HttpContext.Request.Query.ContainsKey("all"); + var showFiltered = Model.Archive.Year != null + || Model.Archive.Category != null + || Model.Archive.Tag != null; + var showMainPage = !(showAll || showFiltered); + + // Set Archive Excerpt to string.Empty if empty if (Library.HtmlTool.IsEmptyHtml(Model.Data.Excerpt ?? string.Empty)) { Model.Data.Excerpt = string.Empty; } + // Set all Archive post Excerpts to string.Empty if empty foreach (var post in Model.Archive.Posts) { if (Library.HtmlTool.IsEmptyHtml(post.Excerpt ?? string.Empty)) { post.Excerpt = string.Empty; } - } } - -
-
-
-

@Model.Data.Title

- @if (!string.IsNullOrWhiteSpace(Model.Data.Excerpt)) - { -
-
- @Html.Raw(Model.Data.Excerpt) -
-
} -
-
- -
- @* Display the blocks of the main Blog page *@ - @foreach (var block in Model.Data.Blocks) - { -
-
- @Html.DisplayFor(m => block, block.GetType().Name) -
-
} - @* Display the teasers for Archive Blog posts *@ -
- @{ var hideTeaser = false; - for (var n = 0; n < posts; n += 2) - { -
- @for (var i = n; i < Math.Min(posts, n + 2); i++) - { -
- -
- @if (i == 0) - { - n--; - break; - }} -
- @if (!hideTeaser && n + 2 < posts && n == 3) - { - // if we have more than 5 teasers, we hide them until "show more" will be clicked - hideTeaser = true; -} } } -
-
+ } +} +@if (showMainPage) +{ + + +} +else +{ + + +} +@section head +{ + @WebApp.MetaTags(Model.Data, generator: false, opengraph: false) +} diff --git a/ClubSite/Pages/DisplayTemplates/AudioBlock.cshtml b/ClubSite/Pages/DisplayTemplates/AudioBlock.cshtml index 10f658a..04beec7 100644 --- a/ClubSite/Pages/DisplayTemplates/AudioBlock.cshtml +++ b/ClubSite/Pages/DisplayTemplates/AudioBlock.cshtml @@ -1,4 +1,4 @@ -@model Piranha.Extend.Blocks.AudioBlock +@model Piranha.Extend.Blocks.AudioBlock? @{ if (Model is null) return; }