From b7518fe85f304fc8ffd62806c604c88b64d55b12 Mon Sep 17 00:00:00 2001 From: StepanovPlaton Date: Thu, 12 Feb 2026 19:39:45 +0400 Subject: [PATCH] Update content and logic --- public/admin/config.yml | 11 ++- src/components/data/projectCard.astro | 58 ++++++++++++- src/components/data/timelineItem.astro | 86 +++++++++++++++++-- ...машнем-сервере-с-офисным-пакетом-collabora.md | 1 - .../projects/home-server-services.json | 2 +- src/content/projects/jellybelly-wiki.json | 2 +- src/content/projects/neural-network.json | 2 +- src/content/projects/osin1000lines.json | 2 +- src/content/worth-mentioning.md | 24 +++--- src/i18n/i18nKey.ts | 1 + src/i18n/languages/en.ts | 3 +- src/i18n/languages/ja.ts | 3 +- src/i18n/languages/ru.ts | 3 +- src/i18n/languages/zh.ts | 3 +- src/pages/projects.astro | 18 ++++ src/utils/content.ts | 6 ++ src/utils/projects.ts | 16 +++- 17 files changed, 206 insertions(+), 35 deletions(-) diff --git a/public/admin/config.yml b/public/admin/config.yml index e80975a..b13894c 100644 --- a/public/admin/config.yml +++ b/public/admin/config.yml @@ -40,12 +40,19 @@ collections: - { label: "Image", name: "image", widget: "image", required: false } - { label: "Category", name: "category", widget: "select", options: ["actual","history","other"] } - { label: "Tech Stack", name: "techStack", widget: "list", default: [] } - - { label: "Status", name: "status", widget: "select", options: ["completed","in-progress","planned","paused"] } + - label: "Status" + name: "status" + widget: "select" + options: ["completed","in-progress","planned","paused"] - { label: "Live Demo", name: "liveDemo", widget: "string", required: false } - { label: "Source Code", name: "sourceCode", widget: "string", required: false } - { label: "Start Date", name: "startDate", widget: "datetime" } - { label: "End Date", name: "endDate", widget: "datetime", required: false } - - { label: "Featured", name: "featured", widget: "boolean", required: false, default: false } + - label: "Featured" + name: "featured" + widget: "boolean" + required: false + default: false - { label: "Tags", name: "tags", widget: "list", required: false, default: [] } - name: "skills" diff --git a/src/components/data/projectCard.astro b/src/components/data/projectCard.astro index 884e8a2..66276e0 100644 --- a/src/components/data/projectCard.astro +++ b/src/components/data/projectCard.astro @@ -133,16 +133,31 @@ const sizeClasses = getSizeClasses(size);

{project.techStack && project.techStack.length > 0 && ( -
+
{project.techStack.slice(0, maxTechStack).map((tech) => ( {tech} ))} {project.techStack.length > maxTechStack && ( - - +{project.techStack.length - maxTechStack} - + <> + {project.techStack.slice(maxTechStack).map((tech) => ( + + {tech} + + ))} + + )}
)} @@ -181,3 +196,38 @@ const sizeClasses = getSizeClasses(size);
+ + diff --git a/src/components/data/timelineItem.astro b/src/components/data/timelineItem.astro index 098cc93..dd45801 100644 --- a/src/components/data/timelineItem.astro +++ b/src/components/data/timelineItem.astro @@ -254,12 +254,32 @@ const itemColor = item.color || "#3B82F6"; {item.skills && item.skills.length > 0 && (
-
- {item.skills.map((skill) => ( +
+ {item.skills.slice(0, 3).map((skill) => ( {skill} ))} + {item.skills.length > 3 && ( + <> + {item.skills.slice(3).map((skill) => ( + + {skill} + + ))} + + + )}
)} @@ -353,16 +373,31 @@ const itemColor = item.color || "#3B82F6";
{item.skills && item.skills.length > 0 && ( -
+
{item.skills.slice(0, 3).map((skill) => ( {skill} ))} {item.skills.length > 3 && ( - - +{item.skills.length - 3} - + <> + {item.skills.slice(3).map((skill) => ( + + {skill} + + ))} + + )}
)} @@ -383,4 +418,41 @@ const itemColor = item.color || "#3B82F6";
-)} \ No newline at end of file +)} + + \ No newline at end of file diff --git a/src/content/posts/nextcloud-на-домашнем-сервере-с-офисным-пакетом-collabora.md b/src/content/posts/nextcloud-на-домашнем-сервере-с-офисным-пакетом-collabora.md index ca58f94..6bfb8aa 100644 --- a/src/content/posts/nextcloud-на-домашнем-сервере-с-офисным-пакетом-collabora.md +++ b/src/content/posts/nextcloud-на-домашнем-сервере-с-офисным-пакетом-collabora.md @@ -3,7 +3,6 @@ title: NextCloud на домашнем сервере с офисным паке published: 2026-02-12T19:26:00.000+04:00 cover: /images/nextcloud.png tags: - - DevOps - Linux draft: false --- diff --git a/src/content/projects/home-server-services.json b/src/content/projects/home-server-services.json index 1b040ea..18bab3b 100644 --- a/src/content/projects/home-server-services.json +++ b/src/content/projects/home-server-services.json @@ -1,6 +1,6 @@ { "sourceCode": "https://git.stepanovplaton.ru/StepanovPlaton/HomeServerServices", - "featured": true, + "featured": false, "liveDemo": "", "startDate": "2025-12-10T08:00:00.000+04:00", "techStack": [ diff --git a/src/content/projects/jellybelly-wiki.json b/src/content/projects/jellybelly-wiki.json index 0cb7020..b49ec0e 100644 --- a/src/content/projects/jellybelly-wiki.json +++ b/src/content/projects/jellybelly-wiki.json @@ -1,6 +1,6 @@ { "sourceCode": "https://git.stepanovplaton.ru/StepanovPlaton/jelly_belly_wiki", - "featured": false, + "featured": true, "liveDemo": "https://jelly-belly-wiki.vercel.app", "startDate": "2024-07-08T08:00:00.000+04:00", "techStack": [ diff --git a/src/content/projects/neural-network.json b/src/content/projects/neural-network.json index 56bc60a..7aea82c 100644 --- a/src/content/projects/neural-network.json +++ b/src/content/projects/neural-network.json @@ -1,6 +1,6 @@ { "sourceCode": "https://git.stepanovplaton.ru/StepanovPlaton/NeuralNetwork", - "featured": false, + "featured": true, "startDate": "2025-10-26T08:00:00.000+04:00", "techStack": [ "C++", diff --git a/src/content/projects/osin1000lines.json b/src/content/projects/osin1000lines.json index cac5d7d..4e410e5 100644 --- a/src/content/projects/osin1000lines.json +++ b/src/content/projects/osin1000lines.json @@ -1,6 +1,6 @@ { "sourceCode": "https://git.stepanovplaton.ru/StepanovPlaton/OSin1000Lines", - "featured": true, + "featured": false, "startDate": "2026-02-03T08:00:00.000+04:00", "techStack": [ "C" diff --git a/src/content/worth-mentioning.md b/src/content/worth-mentioning.md index a508b53..b7fd863 100644 --- a/src/content/worth-mentioning.md +++ b/src/content/worth-mentioning.md @@ -1,35 +1,35 @@ # Это интересно! -Раз уж у меня появился свой уголок в интернете, я посчитал нужным поделиться с вами классными проектами других людей. Здесь вы найдёте и другие сайты, и книги, и видеоигры, от популярных до нишевых — **всё, что я хочу показать миру**. +Раз уж у меня появился свой уголок в интернете, решил поделиться с тобой классными проектами других людей. Здесь ты найдёшь и другие сайты, и книги, и видеоигры, от популярных до нишевых — **всё, что я хочу показать миру**. Надеюсь, тебе будет интересно! ## О дварфах! История моей аватарки (стилистики этого сайта, моего сервера и много чего ещё) берёт своё начало с **[легендарной игры DwarfFortress](http://www.bay12games.com/dwarves/)**. Эта игра для меня пример **гениальности, усидчивости и абсурда** в одном лице.
- Я не могу советовать её вам (потому что это игра не для всех), но был обязан упомянуть на своём сайте + Я не могу советовать её тебе (потому что это игра не для всех), но был обязан упомянуть на своём сайте Её движок настолько сложен, что долгое время к нему не могли добавить графику. За **более чем 20 лет разработки** она готова менее чем наполовину, её делают два брата на пожертвования от фанатов, и при всём этом ей вдохновлялись создатели Minecraft и Rimworld, а в 2013 Нью-Йоркский музей современного искусства включил игру в свою коллекцию. -Это лучший симулятор историй. Обязательно почитайте [историю крепости Боутмёрдед](https://dtf.ru/games/22946-legendy-dwarf-fortress-saga-o-padenii-kreposti-boutmerded) — эти легенды тянут на эпичный фильм от Netflix, но это просто обычная игра в DwarfFortress. Да, здесь можно тренировать дварфов бегать на костылях быстрее, чем на ногах, стреляя в них монетками. Да, на вас может напасть огромная адская автоматически сгенерированная... попа. И да, ваши дварфы могут умереть не только от гоблинов, но и от кошек, безумия, миазмов, одинаковой выпивки и даже сушняка... +Это лучший симулятор историй. Обязательно почитай [историю крепости Боутмёрдед](https://dtf.ru/games/22946-legendy-dwarf-fortress-saga-o-padenii-kreposti-boutmerded) — эти легенды тянут на эпичный фильм от Netflix, но это просто обычная игра в DwarfFortress. Да, здесь можно тренировать дварфов бегать на костылях быстрее, чем на ногах, стреляя в них монетками. Да, на тебя может напасть огромная адская автоматически сгенерированная... попа. И да, твои дварфы могут умереть не только от гоблинов, но и от кошек, безумия, миазмов, одинаковой выпивки и даже сушняка... Эта игра не для всех, но я боюсь в неё заходить, потому что потом не могу выйти. -И помните... Проигрывать весело! +И помни... Проигрывать весело!
## Карандаш и Самоделкин -У всякой истории есть начало. Я начал свою историю отсюда: [Блог команды "Карандаш и Самоделкин"](https://karandashsamodelkin.blogspot.com). Передавайте привет маленькому мне и **большое спасибо моему отцу**! +У всякой истории есть начало. Я начал свою историю отсюда: [Блог команды "Карандаш и Самоделкин"](https://karandashsamodelkin.blogspot.com). Передай привет маленькому мне и **огромное спасибо моему отцу**! ## Классные сайты -Интернет огромен, и в нём куча страниц. Некоторые популярны, другие не очень, но эти особенно интересны: +Интернет огромен, и в нём куча страниц. Некоторые популярны, другие не очень, но эти особенно зацепили меня: + [Онлайн книга Linux From Scratch](https://linuxfromscratch.org) — бесплатное руководство по созданию своей GNU/Linux системы из исходного кода (с нуля). Лучшее развлечение на вечер для админа. + [Этаж 796](https://floor796.com) — проект русского художника, который объединил на 796 этаже космической станции всех самых знаковых персонажей из мемов, фильмов, комиксов и сериалов. Тут залип на 2 часа... -+ [SCP Foundation](https://scpfoundation.net) — открытая научно-фантастическая онлайн вселенная. Мурашки по коже, невозможно оторваться. Обязательно прочтите [SCP-079 — Старый ИИ](https://scpfoundation.net/scp-079) и [Хаб отдела антимеметики](https://scpfoundation.net/antimemetics-division-hub). -+ [CashGo](https://cashgo.ru) — онлайн игра, тренажёр финансового интеллекта. Здесь я успел ухватить кусочек старого интернета с ламповыми форумами. Спасибо за детство, передавайте привет Оксюше, Пингвинатко, Успеху и Лису! ++ [SCP Foundation](https://scpfoundation.net) — открытая научно-фантастическая онлайн вселенная. Мурашки по коже, невозможно оторваться. Обязательно прочитай [SCP-079 — Старый ИИ](https://scpfoundation.net/scp-079) и [Хаб отдела антимеметики](https://scpfoundation.net/antimemetics-division-hub). ++ [CashGo](https://cashgo.ru) — онлайн игра, тренажёр финансового интеллекта. Здесь я успел ухватить кусочек старого интернета с ламповыми форумами. Спасибо за детство, передай привет Оксюше, Пингвинатко, Успеху и Лису! + [Неолурк](https://neolurk.org) — народная википедия. ## IT @@ -38,7 +38,7 @@ + [KISS](https://ru.wikipedia.org/wiki/KISS_(принцип)) — делай проще, тупица. + [Быстрый обратный квадратный корень](https://ru.wikipedia.org/wiki/Быстрый_обратный_квадратный_корень) — магическая функция приближённого вычисления $1/\sqrt{x}$ из Quake. + [В††](https://neolurk.org/wiki/В%2B%2B) — язык программирования русских богатырей. -+ [Suckless](https://suckless.org) — эталон минимализма. Обязательно зацените [dwm](https://dwm.suckless.org) и [st](https://st.suckless.org). ++ [Suckless](https://suckless.org) — эталон минимализма. Обязательно зацени [dwm](https://dwm.suckless.org) и [st](https://st.suckless.org). + [9600 бод и все-все-все](https://lib.ru/ANEKDOTY/9600.txt) — Винни Пух стал хакером времён FIDONET. + [Nand2Tetris](https://www.nand2tetris.org) — собираем 16-битный компьютер из логических блоков, пишем компилятор, операционную систему и видеоигры. Курс от MIT. @@ -63,7 +63,7 @@ ## Книги -Я не очень люблю читать книги, но просто обожаю слушать их аудиоверсии. Это книги которые кажутся мне классными. Я специально не стал писать их в список, иначе просто не смог бы определить порядок. Некоторые из них полезные, некоторые развлекательные, некоторые известные, другие нет. Может быть ты найдёшь здесь что-то для себя! +Я не очень люблю читать книги, но просто обожаю слушать их аудиоверсии. Это книги, которые кажутся мне классными. Я специально не стал писать их в список по порядку, иначе просто не смог бы определить, какая лучше. Некоторые из них полезные, некоторые развлекательные, некоторые известные, другие нет. Может быть, ты найдёшь здесь что-то для себя! | | | | |---|---|---| @@ -94,7 +94,7 @@ ## Музыка + [ГРОТ](https://grotmusic.ru) - не просто музыка, а текст и глубокий смысл. -+ [HTP](https://vk.com/nii_rap) - если вы из IT просто полистайте, это весело. ++ [HTP](https://vk.com/nii_rap) - если ты из IT просто полистай, это весело. ## Кумиры @@ -106,6 +106,6 @@ ## Разное -Это просто классные вещи, зацените их! +Это просто классные вещи, зацени их! + [Цикада 3301](https://habr.com/ru/companies/ruvds/articles/714806/) — одна из самых больших загадок интернета 2010-х. \ No newline at end of file diff --git a/src/i18n/i18nKey.ts b/src/i18n/i18nKey.ts index b6e1359..2e708d6 100644 --- a/src/i18n/i18nKey.ts +++ b/src/i18n/i18nKey.ts @@ -87,6 +87,7 @@ enum I18nKey { projectsInProgress = "projectsInProgress", projectsTechStack = "projectsTechStack", projectsFeatured = "projectsFeatured", + projectsInWork = "projectsInWork", projectsPlanned = "projectsPlanned", projectsPaused = "projectsPaused", projectsDemo = "projectsDemo", diff --git a/src/i18n/languages/en.ts b/src/i18n/languages/en.ts index 597889d..55919ad 100644 --- a/src/i18n/languages/en.ts +++ b/src/i18n/languages/en.ts @@ -90,7 +90,8 @@ export const en: Translation = { [Key.projectsCompleted]: "Completed", [Key.projectsInProgress]: "In Progress", [Key.projectsTechStack]: "Tech Stack Statistics", - [Key.projectsFeatured]: "Featured Projects", + [Key.projectsFeatured]: "Must See Projects", + [Key.projectsInWork]: "Currently Working On", [Key.projectsPlanned]: "Planned", [Key.projectsPaused]: "Paused", [Key.projectsDemo]: "Live Demo", diff --git a/src/i18n/languages/ja.ts b/src/i18n/languages/ja.ts index 01224c4..f65c850 100644 --- a/src/i18n/languages/ja.ts +++ b/src/i18n/languages/ja.ts @@ -90,7 +90,8 @@ export const ja: Translation = { [Key.projectsCompleted]: "完了", [Key.projectsInProgress]: "進行中", [Key.projectsTechStack]: "技術スタック統計", - [Key.projectsFeatured]: "注目プロジェクト", + [Key.projectsFeatured]: "必見プロジェクト", + [Key.projectsInWork]: "現在開発中", [Key.projectsPlanned]: "予定", [Key.projectsPaused]: "一時停止", [Key.projectsDemo]: "ライブデモ", diff --git a/src/i18n/languages/ru.ts b/src/i18n/languages/ru.ts index e53f844..e461b9c 100644 --- a/src/i18n/languages/ru.ts +++ b/src/i18n/languages/ru.ts @@ -89,7 +89,8 @@ export const ru: Translation = { [Key.projectsCompleted]: "Завершён", [Key.projectsInProgress]: "В разработке", [Key.projectsTechStack]: "Статистика технологий", - [Key.projectsFeatured]: "Сейчас я работаю над этим", + [Key.projectsFeatured]: "Обязательно посмотрите эти проекты", + [Key.projectsInWork]: "Сейчас я работаю над этим", [Key.projectsPlanned]: "Запланированных", [Key.projectsPaused]: "Приостановлен", [Key.projectsDemo]: "Демо", diff --git a/src/i18n/languages/zh.ts b/src/i18n/languages/zh.ts index 04db356..17b0a96 100644 --- a/src/i18n/languages/zh.ts +++ b/src/i18n/languages/zh.ts @@ -90,7 +90,8 @@ export const zh: Translation = { [Key.projectsCompleted]: "已完成", [Key.projectsInProgress]: "进行中", [Key.projectsTechStack]: "技术栈统计", - [Key.projectsFeatured]: "精选项目", + [Key.projectsFeatured]: "必看项目", + [Key.projectsInWork]: "正在开发中", [Key.projectsPlanned]: "计划中", [Key.projectsPaused]: "已暂停", [Key.projectsDemo]: "在线演示", diff --git a/src/pages/projects.astro b/src/pages/projects.astro index c3b64fb..93bd793 100644 --- a/src/pages/projects.astro +++ b/src/pages/projects.astro @@ -9,6 +9,7 @@ import { getProjectStats, getProjectsByCategory, getFeaturedProjects, + getInWorkProjects, getAllTechStack, } from "@utils/projects"; import { UNCATEGORIZED } from "@constants/constants"; @@ -25,6 +26,7 @@ const subtitle = LinkPresets[LinkPreset.Projects].description; // 获取项目统计信息 const stats = getProjectStats(); const featuredProjects = getFeaturedProjects(); +const inWorkProjects = getInWorkProjects(); const allTechStack = getAllTechStack(); // 定义分类顺序 @@ -105,6 +107,22 @@ const getCategoryText = (category: string) => { )} + + {inWorkProjects.length > 0 && ( +
+

+ {i18n(I18nKey.projectsInWork)} + + ({inWorkProjects.length}) + +

+
+ {inWorkProjects.map((project) => ( + + ))} +
+
+ )}
{categories.map((category) => { diff --git a/src/utils/content.ts b/src/utils/content.ts index 5231ff8..aac34c1 100644 --- a/src/utils/content.ts +++ b/src/utils/content.ts @@ -3,6 +3,7 @@ import { type CollectionEntry, getCollection } from "astro:content"; import { getCategoryUrl } from "@utils/url"; import { i18n } from "@i18n/translation"; import I18nKey from "@i18n/i18nKey"; +import { UNCATEGORIZED } from "@constants/constants"; // // Retrieve posts and sort them by publication date @@ -110,7 +111,12 @@ export async function getCategoryList(): Promise { }); const ret: Category[] = []; + const uncategorizedKey = i18n(I18nKey.uncategorized); for (const c of lst) { + // Исключаем категорию "Без категории" из списка + if (c === uncategorizedKey) { + continue; + } ret.push({ name: c, count: count[c], diff --git a/src/utils/projects.ts b/src/utils/projects.ts index 98f1c65..9250b60 100644 --- a/src/utils/projects.ts +++ b/src/utils/projects.ts @@ -58,6 +58,9 @@ export const getProjectsByCategory = (category?: string) => { } else { filteredProjects = projectsData.filter((p) => p.category === category); } + // Exclude featured projects and in-progress projects from category lists + // (they are shown in their dedicated sections) + filteredProjects = filteredProjects.filter((p) => !p.featured && p.status !== "in-progress"); // Sort by startDate in descending order (newest first) return filteredProjects.sort((a, b) => { const dateA = new Date(a.startDate).getTime(); @@ -68,7 +71,18 @@ export const getProjectsByCategory = (category?: string) => { // Get featured projects export const getFeaturedProjects = () => { - return projectsData.filter((p) => p.featured); + return projectsData.filter((p) => p.featured === true); +}; + +// Get in-work projects (in-progress status, excluding featured) +export const getInWorkProjects = () => { + return projectsData + .filter((p) => p.status === "in-progress" && !p.featured) + .sort((a, b) => { + const dateA = new Date(a.startDate).getTime(); + const dateB = new Date(b.startDate).getTime(); + return dateB - dateA; + }); }; // Get all tech stacks