Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@

### Добавлено

- Глобальный полнотекстовый поиск с `⌘ K` / `Ctrl K`, клавиатурной навигацией, подсветкой совпадений и понятными empty states.
- Страницы «О проекте», «Архитектура» и «Помочь StackMIREA».
- Опциональные учебные метаданные, прогресс курса в браузере, стандарт образовательной страницы и MDX-компоненты для самопроверки, иллюстраций и сворачиваемого кода.
- Новый векторный логотип StackMIREA для README.
- `AGENTS.md` с инструкциями для кодовых агентов.
- Этот журнал изменений.

### Изменено

- Футер сайта получил новую адаптивную структуру с навигацией, каналами связи, ссылками на поддержку и отдельными карточками лицензий для кода и учебных материалов.
- Главная страница и каталог перестроены вокруг поиска и наполненных направлений; пустые дисциплины вынесены в блок «Скоро появятся».
- Страницы направлений получили roadmap, прогресс и структуру mini-course; статьи — метаданные, mobile TOC и навигацию только внутри своего курса.
- Обновлены репрезентативные материалы Java MVC, AI/KNN и Big Data по новому образовательному стандарту.
- Упрощены header, footer и представление команды; улучшены focus states, reduced motion и адаптивность контента.
- Светлая и тёмная темы сайта переведены с монохромной палитры на фиолетовую; обновлены фоновые градиенты, акценты, состояния фокуса и оформление документации.
- Фирменные SVG- и PNG-знаки приведены к новой фиолетовой палитре; социальное превью обновлено в формате 1200×630.
- README получил новую структуру, навигацию, badges, схему контентного pipeline и актуальные команды.
Expand All @@ -24,6 +30,7 @@

### Исправлено

- Исправлены пути статических ассетов и favicon для production `basePath` на GitHub Pages.
- Исправлен синтаксис YAML в шаблонах issues со значениями, содержащими двоеточие.

## Как вести журнал
Expand Down
15 changes: 15 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ order: 1
---
```

При необходимости добавьте тип (`theory`, `practice`, `notebook`, `guide`, `reference`), теги, сложность, дату обновления, ожидаемое время и статус:

```yaml
type: practice
tags:
- Java
- MVC
difficulty: intermediate
updatedAt: 2026-09-02
estimatedMinutes: 20
status: published
```

Статусы `draft`, `published` и `archived` позволяют управлять жизненным циклом страницы. Черновики не попадают в production manifest. Подробная структура страницы описана в [стандарте учебного материала](./docs/algorithms/content-standard.mdx).

Вместо `order` можно использовать `sidebar_position`. Для нового учебного трека добавьте запись в `lib/tracks.json` и индексную страницу `docs/<track>/index.mdx`.

Хороший материал:
Expand Down
35 changes: 35 additions & 0 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Metadata } from "next";
import Link from "next/link";
import { ArrowRight, BookOpenText, Code2, Github, Search } from "lucide-react";

import { GitHubUserBadge } from "@/components/ui/GitHubUserBadge";
import { buttonVariants } from "@/components/ui/button";
import { getAuthorsWithSummary } from "@/lib/contributors";
import { buildPageMetadata } from "@/lib/seo";
import { cn, REPO_URL } from "@/lib/utils";

export const metadata: Metadata = buildPageMetadata({ title: "О проекте", description: "Зачем существует StackMIREA, для кого он сделан и как устроена открытая база учебных материалов.", pathname: "/about" });

export default function AboutPage() {
const authors = getAuthorsWithSummary();
const maintainer = authors.find((author) => author.github.toLowerCase() === "minkinad");
const contributors = authors.filter((author) => author.github.toLowerCase() !== "minkinad");

return (
<div className="mx-auto w-full max-w-5xl px-4 py-12 sm:px-6 sm:py-16 lg:px-8">
<header className="max-w-3xl"><p className="text-sm font-medium text-primary">О проекте</p><h1 className="mt-3 text-balance text-4xl font-semibold tracking-tight sm:text-5xl">StackMIREA превращает разрозненные учебные файлы в понятную базу знаний</h1><p className="mt-5 text-lg leading-8 text-muted-foreground">Это открытая статическая платформа с практиками, ноутбуками и разборами по IT-дисциплинам РТУ МИРЭА.</p></header>

<div className="mt-12 grid gap-5 md:grid-cols-3">
{[{ icon: BookOpenText, title: "Для студентов", text: "Чтобы быстро найти тему, пройти материалы по порядку и вернуться к нужному фрагменту." }, { icon: Search, title: "Для самостоятельного обучения", text: "Чтобы искать по содержимому, а не помнить название дисциплины или файла." }, { icon: Code2, title: "Для авторов", text: "Чтобы публиковать воспроизводимые материалы в одном проверяемом формате." }].map((item) => <article key={item.title} className="rounded-2xl border border-border bg-card/60 p-5"><item.icon className="size-5 text-primary" /><h2 className="mt-4 font-semibold">{item.title}</h2><p className="mt-2 text-sm leading-6 text-muted-foreground">{item.text}</p></article>)}
</div>

<section className="mt-14 border-t border-border pt-10"><h2 className="text-2xl font-semibold tracking-tight">Почему появился проект</h2><p className="mt-4 max-w-3xl text-base leading-7 text-muted-foreground">Полезные практики часто остаются в локальных папках, чатах и отдельных репозиториях. StackMIREA сохраняет их в читаемом MDX-формате, строит единый каталог и делает содержание доступным через поиск.</p></section>

<section className="mt-12"><h2 className="text-2xl font-semibold tracking-tight">Как устроен контент</h2><p className="mt-4 max-w-3xl text-base leading-7 text-muted-foreground">Канонические материалы находятся в <code className="rounded bg-muted px-1.5 py-0.5">docs/</code>. Перед публикацией проверяются метаданные, внутренние ссылки, структура треков и поисковый индекс. Сайт собирается статически и не требует аккаунта или backend.</p><Link href="/architecture" className={cn(buttonVariants({ variant: "outline" }), "mt-5")}>Посмотреть архитектуру <ArrowRight className="size-4" /></Link></section>

<section id="team" className="mt-14 border-t border-border pt-10"><h2 className="text-2xl font-semibold tracking-tight">Команда</h2><p className="mt-2 text-sm leading-6 text-muted-foreground">Роли отражают реальный вклад в проект без корпоративной иерархии.</p>{maintainer ? <div className="mt-6 max-w-md rounded-2xl border border-border bg-card/60 p-5"><h3 className="font-semibold">Alexander Minkin</h3><GitHubUserBadge person={maintainer} description="Creator & Maintainer" className="mt-3" /><p className="mt-3 text-sm leading-6 text-muted-foreground">Разработка платформы, сопровождение контента и публикация проекта.</p></div> : null}{contributors.length ? <div className="mt-6"><h3 className="text-lg font-semibold">Участники</h3><div className="mt-3 grid gap-3 sm:grid-cols-2">{contributors.map((author) => <div key={author.github} className="rounded-xl border border-border bg-card/50 p-4"><GitHubUserBadge person={author} description="Content Contributor" /><p className="mt-2 text-xs text-muted-foreground">{author.docsCount} публикаций</p></div>)}</div></div> : null}</section>

<section className="mt-14 rounded-3xl border border-border bg-card/60 p-6 sm:p-8"><Github className="size-6 text-primary" /><h2 className="mt-4 text-2xl font-semibold tracking-tight">Open Source</h2><p className="mt-3 max-w-2xl text-sm leading-7 text-muted-foreground">Исходный код открыт по MIT, учебные материалы — по CC BY-NC-SA 4.0. Предложения и исправления принимаются через GitHub.</p><Link href={REPO_URL} target="_blank" rel="noreferrer" className={cn(buttonVariants(), "mt-5")}>Открыть репозиторий <ArrowRight className="size-4" /></Link></section>
</div>
);
}
33 changes: 33 additions & 0 deletions app/architecture/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Metadata } from "next";
import Link from "next/link";
import { ArrowRight, Boxes, FileCode2, Github, Search, ShieldCheck } from "lucide-react";

import { buildPageMetadata } from "@/lib/seo";
import { REPO_URL } from "@/lib/utils";

export const metadata: Metadata = buildPageMetadata({ title: "Архитектура платформы", description: "Реальный путь контента StackMIREA от MDX-файла до статической публикации в GitHub Pages.", pathname: "/architecture" });

const stack = [
["Next.js 14", "App Router, маршруты и статический export."],
["TypeScript", "Строгая типизация компонентов и data layer."],
["MDX", "Учебный текст вместе с переиспользуемыми компонентами."],
["Shiki", "Build-time подсветка синтаксиса без тяжёлого runtime."],
["GitHub Actions", "Проверки качества и воспроизводимая сборка."],
["GitHub Pages", "Хостинг готовых статических файлов с basePath."]
];

export default function ArchitecturePage() {
return (
<div className="mx-auto w-full max-w-5xl px-4 py-12 sm:px-6 sm:py-16 lg:px-8">
<header className="max-w-3xl"><p className="text-sm font-medium text-primary">Engineering</p><h1 className="mt-3 text-balance text-4xl font-semibold tracking-tight sm:text-5xl">Как StackMIREA превращает MDX в статическую образовательную платформу</h1><p className="mt-5 text-lg leading-8 text-muted-foreground">Один pipeline отвечает за навигацию, страницы, поиск и проверку качества — без отдельной CMS и backend.</p></header>

<section className="mt-12 rounded-3xl border border-border bg-card/60 p-5 sm:p-8" aria-labelledby="flow-title"><h2 id="flow-title" className="text-2xl font-semibold tracking-tight">Путь материала</h2><div className="mt-6 overflow-x-auto"><div className="min-w-[680px] font-mono text-sm"><div className="grid grid-cols-[1fr_auto_1fr_auto_1fr] items-center gap-3"><div className="rounded-xl border border-border bg-background p-4"><FileCode2 className="mb-3 size-5 text-primary" />docs/**/*.mdx</div><ArrowRight className="size-5 text-muted-foreground" /><div className="rounded-xl border border-border bg-background p-4"><ShieldCheck className="mb-3 size-5 text-primary" />Validation + manifest</div><ArrowRight className="size-5 text-muted-foreground" /><div className="rounded-xl border border-border bg-background p-4"><Boxes className="mb-3 size-5 text-primary" />Next.js static build</div></div><div className="mx-auto my-3 h-8 w-px bg-border" /><div className="mx-auto grid max-w-xl grid-cols-3 gap-3 text-center"><div className="rounded-xl border border-border bg-background p-3">Navigation</div><div className="rounded-xl border border-border bg-background p-3">Docs pages</div><div className="rounded-xl border border-border bg-background p-3"><Search className="mx-auto mb-1 size-4" />Search index</div></div><div className="mx-auto my-3 h-8 w-px bg-border" /><div className="mx-auto max-w-xs rounded-xl border border-primary/30 bg-primary/5 p-4 text-center"><Github className="mx-auto mb-2 size-5 text-primary" />GitHub Pages</div></div></div></section>

<section className="mt-12"><h2 className="text-2xl font-semibold tracking-tight">Компоненты pipeline</h2><div className="mt-5 grid gap-4 sm:grid-cols-2">{[{ title: "Источник", text: "Только docs/ является каноническим источником учебных материалов." }, { title: "Content manifest", text: "Содержит маршруты, метаданные, TOC, темы, превью и данные для навигации." }, { title: "Поисковый индекс", text: "На build-time материал делится на смысловые фрагменты и получает ключевые слова." }, { title: "Quality gates", text: "CI проверяет frontmatter, дубликаты, ссылки, orphan pages, TypeScript, тесты и build." }].map((item) => <article key={item.title} className="rounded-2xl border border-border bg-card/50 p-5"><h3 className="font-semibold">{item.title}</h3><p className="mt-2 text-sm leading-6 text-muted-foreground">{item.text}</p></article>)}</div></section>

<section className="mt-12"><h2 className="text-2xl font-semibold tracking-tight">Технологии</h2><dl className="mt-5 divide-y divide-border overflow-hidden rounded-2xl border border-border bg-card/50">{stack.map(([name, description]) => <div key={name} className="grid gap-1 p-4 sm:grid-cols-[180px_1fr]"><dt className="font-medium">{name}</dt><dd className="text-sm leading-6 text-muted-foreground">{description}</dd></div>)}</dl></section>

<Link href={REPO_URL} target="_blank" rel="noreferrer" className="mt-10 inline-flex min-h-11 items-center gap-2 text-sm font-medium text-primary">Изучить исходный код <ArrowRight className="size-4" /></Link>
</div>
);
}
10 changes: 4 additions & 6 deletions app/ask/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@ export default function AskPage() {
<div className="relative max-w-4xl">
<p className="inline-flex items-center gap-2 rounded-full border border-border/80 bg-background/70 px-3 py-1 text-xs text-muted-foreground">
<Sparkles className="size-3.5" />
Новый способ навигации по StackMIREA
Поиск ответа по содержимому
</p>
<h1 className="mt-5 text-balance text-4xl font-semibold tracking-tight sm:text-5xl">
Семантический поиск и
<br />
“Спроси StackMIREA”
Спроси StackMIREA
</h1>
<p className="mt-5 max-w-3xl text-pretty text-base leading-7 text-muted-foreground sm:text-lg">
Ищи не только по заголовкам. Формулируй вопрос естественным языком, а движок подберёт материалы по теме,
смыслу и совпадающим фрагментам внутри документации.
Глобальный поиск находит конкретную страницу. Здесь можно сформулировать вопрос естественным языком —
движок подберёт подходящие материалы и покажет релевантные фрагменты.
</p>
<div className="mt-6 inline-flex items-center gap-2 rounded-2xl border border-border/70 bg-background/70 px-4 py-2 text-sm text-muted-foreground">
<BrainCircuit className="size-4 text-primary" />
Expand Down
Loading
Loading