Compare commits
No commits in common. "d758bb3b3ff79e772395da2a2217dcfcc6580b56" and "86dff5272e639902f2c156441e73cbb66c9674b0" have entirely different histories.
d758bb3b3f
...
86dff5272e
12 changed files with 3 additions and 246 deletions
1
src/app.d.ts
vendored
1
src/app.d.ts
vendored
|
|
@ -23,7 +23,6 @@ declare global {
|
|||
title: string;
|
||||
thumbnail?: string;
|
||||
date?: string;
|
||||
dateChanged?: string;
|
||||
description: string;
|
||||
publisher: string;
|
||||
published?: boolean;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
---
|
||||
title: 'Тестовый блог'
|
||||
date:
|
||||
dateChanged: '2025-09-29'
|
||||
description: 'Немного о самом сайте'
|
||||
projects: ['ts-hldm']
|
||||
---
|
||||
|
||||
# ПРИВЕТ !
|
||||
|
||||
Добро пожаловать на наш первый блог-пост!
|
||||
|
||||
<Img src="wasd_perelesoq_game_jam_2025.png" />
|
||||
Добро пожаловать на наш первый блог-пост!
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { resolveBlogPath } from '$lib/util/Blogs';
|
||||
|
||||
export let src: string;
|
||||
export let caption: string;
|
||||
export let alt: string = '';
|
||||
</script>
|
||||
|
||||
<div class="text-center">
|
||||
<img
|
||||
class="mx-auto mb-0 flex justify-center rounded-lg"
|
||||
class:caption-img={caption}
|
||||
src={resolveBlogPath(page.params.slug, src)}
|
||||
alt={alt ? alt : src}
|
||||
/>
|
||||
{#if caption}
|
||||
<p style="margin-top: 0px;">{caption}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Icon from '@iconify/svelte';
|
||||
</script>
|
||||
|
||||
<section class="flex flex-col sm:flex-row">
|
||||
<div class="flex flex-row items-center gap-2 bg-blue-500 p-2 text-slate-50">
|
||||
<Icon width={32} height={32} icon={'material-symbols:info'} color={'#f8fafc'} />
|
||||
<span class="sm:hidden">Обратите внимание</span>
|
||||
</div>
|
||||
<div class="bg-blue-50 p-4 sm:grow">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
import path from 'path';
|
||||
|
||||
export const THUMBNAIL_DEFAULT = "https://teasanctuary.ru/common/background-day.webp";
|
||||
|
||||
export async function fetchPostsSorted() {
|
||||
const allPosts = await fetchPosts();
|
||||
|
||||
|
|
@ -10,7 +8,7 @@ export async function fetchPostsSorted() {
|
|||
.filter((a) => !!a.date)
|
||||
.sort((a, b) => {
|
||||
return new Date(b.date!).valueOf() - new Date(a.date!).valueOf();
|
||||
});
|
||||
});
|
||||
|
||||
return sortedPosts;
|
||||
};
|
||||
|
|
@ -33,11 +31,3 @@ export async function fetchPosts() {
|
|||
|
||||
return allPosts;
|
||||
};
|
||||
|
||||
export function resolveBlogPath(slug?: string, src?: string) {
|
||||
if (!src) return null;
|
||||
|
||||
return src.startsWith('http://') || src.startsWith('https://')
|
||||
? src
|
||||
: `/blog/${slug}/${src}`;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
import { fetchPostsSorted } from "$src/lib/util/Blogs";
|
||||
|
||||
export async function load() {
|
||||
return { title: "Блог", description: "Новости и заметки проектов Tea Sanctuary", posts: await fetchPostsSorted() };
|
||||
}
|
||||
|
|
@ -1,25 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import Icon from '@iconify/svelte';
|
||||
import SocialHyperlink from '$src/lib/components/SocialHyperlink.svelte';
|
||||
import InfoBlock from '$src/lib/components/InfoBlock.svelte';
|
||||
|
||||
function groupPostsByMonthYear(posts: App.BlogPost[]) {
|
||||
const groupedPosts = new Map<string, App.BlogPost[]>();
|
||||
|
||||
posts.forEach((post) => {
|
||||
const key = new Date(post.date!).toLocaleString('default', {
|
||||
month: 'long',
|
||||
year: 'numeric'
|
||||
});
|
||||
if (!groupedPosts.has(key)) groupedPosts.set(key, []);
|
||||
groupedPosts.get(key)?.push(post);
|
||||
});
|
||||
|
||||
return groupedPosts;
|
||||
}
|
||||
|
||||
const groupedPosts = groupPostsByMonthYear(page.data.posts);
|
||||
import SocialButton from '$lib/components/SocialButton.svelte';
|
||||
</script>
|
||||
|
||||
<section class="hero flex shrink-0 flex-col items-center justify-center gap-5 overflow-hidden p-4">
|
||||
|
|
@ -34,63 +14,6 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<InfoBlock>
|
||||
Подпишитесь на нашу <SocialHyperlink href="/blog/rss.xml">RSS ленту</SocialHyperlink>, чтобы не
|
||||
пропускать новые посты!
|
||||
</InfoBlock>
|
||||
|
||||
<section class="flex flex-col items-stretch p-2 pb-8 md:p-4">
|
||||
{#each groupedPosts.entries() as [monthYear, postsInMonthYear]}
|
||||
<h1
|
||||
class="mt-10 mb-4 text-left text-2xl font-bold underline decoration-4 md:text-center md:text-4xl md:decoration-8"
|
||||
>
|
||||
{monthYear}
|
||||
</h1>
|
||||
<div class="flex flex-col flex-wrap items-stretch gap-4 md:flex-row md:justify-center">
|
||||
{#each postsInMonthYear as post, i}
|
||||
<a
|
||||
href="/blog/{post.slug}"
|
||||
class="flex flex-row justify-stretch overflow-hidden rounded-lg bg-slate-100 text-slate-950 drop-shadow-xl transition-all hover:drop-shadow-2xl md:flex-col md:justify-baseline"
|
||||
>
|
||||
<div class="relative h-auto w-full basis-1/3 md:h-48 md:basis-auto">
|
||||
{#if post.thumbnail}
|
||||
<img
|
||||
class="absolute h-full w-full object-cover"
|
||||
src={`/blog/${post.slug}/${post.thumbnail}`}
|
||||
alt="thumbnail"
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="flex w-full flex-col justify-center p-4 break-words md:p-8">
|
||||
<div class="flex flex-row flex-wrap justify-between gap-4 pb-4">
|
||||
<div class="flex items-center text-lg font-bold">
|
||||
<Icon
|
||||
icon="material-symbols:calendar-today"
|
||||
class="mr-3"
|
||||
style="transform: scale( 1.3 )"
|
||||
/>
|
||||
<p>
|
||||
{new Date(post.date!).toLocaleString('default', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 class="text-3xl font-bold">{post.title}</h2>
|
||||
|
||||
{#if post.description}
|
||||
<p>{post.description}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</section>
|
||||
|
||||
<style>
|
||||
@import '$src/app.css';
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import InfoBlock from '$src/lib/components/InfoBlock.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import Icon from '@iconify/svelte';
|
||||
|
||||
export let data: PageData;
|
||||
|
||||
const isPublic = !!data.blogPost.date;
|
||||
</script>
|
||||
|
||||
<base target="_blank" />
|
||||
|
||||
<svelte:head>
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
</svelte:head>
|
||||
|
||||
<section class="hero flex shrink-0 flex-col items-center justify-center gap-5 overflow-hidden p-4">
|
||||
<div
|
||||
class="flex flex-col flex-nowrap items-center justify-center gap-3 lg:flex-row lg:flex-nowrap"
|
||||
>
|
||||
<div class="text-left">
|
||||
<h1>{data.blogPost.title}</h1>
|
||||
{#if data.blogPost.description}
|
||||
<h2 class="text-gray">{data.blogPost.description}</h2>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
class="flex shrink-0 flex-col items-center justify-center p-4 font-bold {isPublic
|
||||
? 'bg-amber-50 text-slate-950'
|
||||
: 'bg-red-500 text-slate-50'} sm:flex-row sm:flex-nowrap sm:gap-5"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<Icon icon="material-symbols:calendar-today" class="mr-3" style="transform: scale( 1.4 )" />
|
||||
<p>
|
||||
{data.blogPost.date
|
||||
? new Date(data.blogPost.date).toLocaleString(undefined, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
})
|
||||
: 'Не опубликован!'}
|
||||
</p>
|
||||
</div>
|
||||
{#if data.blogPost.dateChanged}
|
||||
<div class="flex items-center font-bold">
|
||||
<Icon icon="material-symbols:update" class="mr-3" style="transform: scale( 1.4 )" />
|
||||
<p>
|
||||
{new Date(data.blogPost.dateChanged).toLocaleString(undefined, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
{#if page.data.blogPost.projects?.length > 0}
|
||||
<InfoBlock>
|
||||
<p>В данной заметке упоминаются наши проекты:</p>
|
||||
<ul>
|
||||
{#each page.data.blogPost.projects as project}
|
||||
<li>{project}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</InfoBlock>
|
||||
{/if}
|
||||
|
||||
<article
|
||||
class="prose
|
||||
lg:prose-lg
|
||||
prose-a:text-blue
|
||||
prose-a:decoration-2
|
||||
prose-a:underline-offset-2
|
||||
hover:prose-a:text-lightblue
|
||||
hover:prose-a:transition-all
|
||||
prose-code:break-words
|
||||
prose-pre:drop-shadow-md
|
||||
bg-white
|
||||
p-4 lg:p-8"
|
||||
>
|
||||
<svelte:component this={data.content} />
|
||||
</article>
|
||||
|
||||
<style>
|
||||
@import '$src/app.css';
|
||||
</style>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import { resolveBlogPath, THUMBNAIL_DEFAULT } from "$src/lib/util/Blogs.js";
|
||||
import { error } from "@sveltejs/kit";
|
||||
|
||||
export async function load({ params }) {
|
||||
let post: any
|
||||
try {
|
||||
post = await import(`$src/blogs/${params.slug}.md`);
|
||||
} catch (ex) {
|
||||
error(404);
|
||||
}
|
||||
const blogPost: App.BlogPost = post.metadata;
|
||||
const thumbnail = resolveBlogPath(params.slug, blogPost.thumbnail ?? THUMBNAIL_DEFAULT);
|
||||
|
||||
return {
|
||||
title: `${blogPost.title} — Блог`,
|
||||
description: blogPost.description,
|
||||
thumbnail: thumbnail,
|
||||
content: post.default,
|
||||
blogPost: {
|
||||
...blogPost
|
||||
}
|
||||
};
|
||||
};
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 449 KiB |
|
Before Width: | Height: | Size: 449 KiB After Width: | Height: | Size: 449 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue