События и первый конкурс #6
5 changed files with 55 additions and 12 deletions
|
|
@ -22,7 +22,7 @@
|
||||||
post,
|
post,
|
||||||
size = BlogCardSize.Both,
|
size = BlogCardSize.Both,
|
||||||
fullHeight = false
|
fullHeight = false
|
||||||
}: { post: App.BlogPost; size: BlogCardSize; fullHeight: boolean } = $props();
|
}: { post: App.BlogPost; size?: BlogCardSize; fullHeight?: boolean } = $props();
|
||||||
|
|
||||||
const type: App.BlogPostType = post.type ?? 'article';
|
const type: App.BlogPostType = post.type ?? 'article';
|
||||||
let isPostNew = $state(false);
|
let isPostNew = $state(false);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ export function postEventStatus(post: App.BlogPost): EventStatus {
|
||||||
export type PostComparer = (a: App.BlogPost, b: App.BlogPost) => number;
|
export type PostComparer = (a: App.BlogPost, b: App.BlogPost) => number;
|
||||||
|
|
||||||
export const sortPostsByPostDate: PostComparer = (a, b) => new Date(b.date!).valueOf() - new Date(a.date!).valueOf();
|
export const sortPostsByPostDate: PostComparer = (a, b) => new Date(b.date!).valueOf() - new Date(a.date!).valueOf();
|
||||||
|
export const sortPostsByPostAndUpdateDate: PostComparer = (a, b) => laterDate(b.date!, b.dateChanged) - laterDate(a.date!, a.dateChanged);
|
||||||
|
|
||||||
function laterDate(a: string, ...dates: (string | undefined)[]): number {
|
function laterDate(a: string, ...dates: (string | undefined)[]): number {
|
||||||
const dateA = new Date(a).valueOf();
|
const dateA = new Date(a).valueOf();
|
||||||
|
|
@ -45,8 +46,6 @@ function laterDate(a: string, ...dates: (string | undefined)[]): number {
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sortPostsByPostAndUpdateDate: PostComparer = (a, b) => laterDate(b.date!, b.dateChanged) - laterDate(a.date!, a.dateChanged);
|
|
||||||
|
|
||||||
export async function fetchPostsSorted(postComparer?: PostComparer) {
|
export async function fetchPostsSorted(postComparer?: PostComparer) {
|
||||||
const allPosts = await fetchPosts();
|
const allPosts = await fetchPosts();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,24 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SocialButton from '$lib/components/SocialButton.svelte';
|
import SocialButton from '$lib/components/SocialButton.svelte';
|
||||||
import { PUBLIC_TS_DISCORD, PUBLIC_TS_TELEGRAM } from '$env/static/public';
|
import { PUBLIC_TS_DISCORD, PUBLIC_TS_TELEGRAM } from '$env/static/public';
|
||||||
import BlogCard, { BlogCardSize } from '$src/lib/components/BlogCard.svelte';
|
import BlogCard, { BlogCardSize } from '$lib/components/BlogCard.svelte';
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import type { PageData } from './$types';
|
import type { PageData } from './$types';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { postIsEventOfInterest } from '$lib/util/Blogs';
|
||||||
|
|
||||||
export let data: PageData;
|
let { data }: { data: PageData } = $props();
|
||||||
|
|
||||||
|
// postIsEventOfInterest(b) ? b.dateEventTo : undefined
|
||||||
|
let posts: App.BlogPost[] = $state(page.data.posts);
|
||||||
|
onMount(() => {
|
||||||
|
const dateToNum = (d: string) => new Date(d).valueOf();
|
||||||
|
posts = posts.sort(
|
||||||
|
(a, b) =>
|
||||||
|
dateToNum(postIsEventOfInterest(b) ? b.dateEventTo! : b.date!) -
|
||||||
|
dateToNum(postIsEventOfInterest(a) ? a.dateEventTo! : a.date!)
|
||||||
|
);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
|
@ -88,9 +101,11 @@
|
||||||
<h1 class="font-disket text-center text-2xl font-bold sm:text-4xl">ПОСЛЕДНИЕ ПОСТЫ</h1>
|
<h1 class="font-disket text-center text-2xl font-bold sm:text-4xl">ПОСЛЕДНИЕ ПОСТЫ</h1>
|
||||||
|
|
||||||
<div class="flex flex-row items-stretch justify-evenly gap-4 overflow-x-auto p-4">
|
<div class="flex flex-row items-stretch justify-evenly gap-4 overflow-x-auto p-4">
|
||||||
{#each page.data.posts as post, i}
|
{#each posts as post, i}
|
||||||
<div class="aspect-3/2 w-80 shrink-0">
|
<div class="aspect-3/2 w-80 shrink-0">
|
||||||
<BlogCard {post} size={BlogCardSize.Short} fullHeight />
|
{#key post}
|
||||||
|
<BlogCard {post} size={BlogCardSize.Short} fullHeight />
|
||||||
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchPostsSorted } from "$src/lib/util/Blogs";
|
import { fetchPostsSorted } from "$lib/util/Blogs";
|
||||||
|
|
||||||
export async function load() {
|
export async function load() {
|
||||||
return { title: "Блог", description: "Новости и заметки проектов Tea Sanctuary", posts: await fetchPostsSorted() };
|
return { title: "Блог", description: "Новости и заметки проектов Tea Sanctuary", posts: await fetchPostsSorted() };
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
import SocialHyperlink from '$src/lib/components/SocialHyperlink.svelte';
|
import SocialHyperlink from '$lib/components/SocialHyperlink.svelte';
|
||||||
import InfoBlock from '$src/lib/components/InfoBlock.svelte';
|
import InfoBlock from '$lib/components/InfoBlock.svelte';
|
||||||
import BlogCard from '$src/lib/components/BlogCard.svelte';
|
import BlogCard, { BlogCardSize } from '$lib/components/BlogCard.svelte';
|
||||||
|
import { postIsEventOfInterest, type PostComparer } from '$lib/util/Blogs';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
function groupPostsByMonthYear(posts: App.BlogPost[]) {
|
function groupPostsByMonthYear(posts: App.BlogPost[]) {
|
||||||
const groupedPosts = new Map<string, App.BlogPost[]>();
|
const groupedPosts = new Map<string, App.BlogPost[]>();
|
||||||
|
|
@ -19,7 +21,20 @@
|
||||||
return groupedPosts;
|
return groupedPosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEventsOfInterest(posts: App.BlogPost[]) {
|
||||||
|
// Сортировка в обратном порядке - чем ближе к завершению, тем раньше в списке
|
||||||
|
const sortPostsByEvent: PostComparer = (a, b) =>
|
||||||
|
new Date(a.dateEventTo!).valueOf() - new Date(b.dateEventTo!).valueOf();
|
||||||
|
|
||||||
|
return posts.filter((a) => postIsEventOfInterest(a)).sort(sortPostsByEvent);
|
||||||
|
}
|
||||||
|
|
||||||
const groupedPosts = groupPostsByMonthYear(page.data.posts);
|
const groupedPosts = groupPostsByMonthYear(page.data.posts);
|
||||||
|
let eventPosts: App.BlogPost[] = $state([]);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
eventPosts = getEventsOfInterest(page.data.posts);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="hero flex shrink-0 flex-col items-center justify-center gap-5 overflow-hidden p-4">
|
<section class="hero flex shrink-0 flex-col items-center justify-center gap-5 overflow-hidden p-4">
|
||||||
|
|
@ -39,6 +54,20 @@
|
||||||
пропускать новые посты!
|
пропускать новые посты!
|
||||||
</InfoBlock>
|
</InfoBlock>
|
||||||
|
|
||||||
|
{#if !!eventPosts && eventPosts.length > 0}
|
||||||
|
<section class="flex flex-col items-stretch bg-amber-50 pt-4">
|
||||||
|
<h1 class="font-disket text-center text-2xl font-bold sm:text-4xl">АКТУАЛЬНЫЕ СОБЫТИЯ</h1>
|
||||||
|
|
||||||
|
<div class="flex flex-row items-stretch justify-evenly gap-4 overflow-x-auto p-4">
|
||||||
|
{#each eventPosts as post, i}
|
||||||
|
<div class="aspect-3/2 w-80 shrink-0">
|
||||||
|
<BlogCard {post} size={BlogCardSize.Short} fullHeight />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<section class="flex flex-col items-stretch p-2 pb-8 md:p-4">
|
<section class="flex flex-col items-stretch p-2 pb-8 md:p-4">
|
||||||
{#each groupedPosts.entries() as [monthYear, postsInMonthYear]}
|
{#each groupedPosts.entries() as [monthYear, postsInMonthYear]}
|
||||||
<h1
|
<h1
|
||||||
|
|
@ -52,4 +81,4 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue