Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Портфолио Sergey Stepanenko

Статический сайт-портфолио на React и Ant Design: проекты, тестовые задания, резюме и контакты. Публикуется на GitHub Pages по адресу https://sergeythrees.github.io. Серверной части нет: весь контент лежит в репозитории.

Возможности

  • Тёмная и светлая темы с переключателем в шапке. Выбор сохраняется в localStorage (ключ st.theme), светлую версию можно открыть ссылкой ?theme=light.
  • Два языка интерфейса, RU и EN, с переключателем в шапке. Выбор сохраняется (ключ st.locale), английскую версию можно открыть ссылкой ?lang=en.
  • Разделы «Проекты», «Работодателям» (со страницами «Резюме» и «Тестовые задания»), «Обо мне» и «Контакты».
  • Страница проекта: описание, факты, стек, галерея скриншотов с превью по клику, ссылки на исходники и кнопка «Открыть приложение».
  • Страница резюме: таймлайн опыта, ключевые результаты, образование, навыки, языки, условия работы и скачивание PDF. Печать корректная — Ctrl+P печатает только резюме, без навигации и шапки сайта.
  • Тестовые задания показываются той же карточкой и той же детальной страницей, что и проекты: отдельный бейдж и свой раздел меню.
  • Lazy-роутинг: главная грузится сразу, остальные страницы — отдельными чанками.

Стек

  • React 19
  • TypeScript
  • Vite
  • antd 6 (+ @ant-design/icons)
  • react-router-dom 7 (HashRouter)

Других зависимостей нет — ни стейт-менеджеров, ни CSS-фреймворков.

Локальный запуск

npm install
npm run dev      # dev-сервер Vite на http://localhost:5173
npm run build    # tsc -b && vite build, результат в dist/
npm run preview  # локальный просмотр собранного dist/

Проверка типов отдельно:

npm run typecheck

Деплой

Деплой автоматический: push в ветку main запускает workflow .github/workflows/deploy.yml. Он выполняет npm ci, затем npm run build, загружает каталог dist как артефакт Pages и публикует его через actions/deploy-pages. Workflow можно запустить и вручную (событие workflow_dispatch).

При первом запуске включите в репозитории Settings → Pages → Source: GitHub Actions.

Почему так:

  • HashRouter — маршрут целиком хранится в hash-части URL, поэтому прямые ссылки на внутренние страницы работают на GitHub Pages без 404.html и редиректов.
  • base: './' в vite.config.ts — ассеты подключаются относительными путями и не ломаются при публикации не из корня домена.

Структура

index.html                     точка входа, метатеги, установка темы до первой отрисовки
vite.config.ts                 base: './', порт dev-сервера 5173, outDir dist
package.json                   скрипты dev / build / preview / typecheck
src/
  main.tsx                     провайдеры (ThemeProvider, LocaleProvider), HashRouter, ConfigProvider
  App.tsx                      маршруты, lazy-загрузка страниц
  i18n/
    LocaleProvider.tsx         контекст локали: t, content, setLocale, toggleLocale
    locales.ts                 список локалей, ключ хранения, метаданные RU/EN
    dictionary/ru.ts           словарь интерфейса, тип Dictionary выводится из него
    dictionary/en.ts           английский словарь, обязан совпадать с ru по ключам
  theme/
    ThemeProvider.tsx          контекст темы: mode, antdTheme, toggleMode
    modes.ts                   тип ThemeMode ('dark' | 'light')
  data/
    types.ts                   типы Content, Project, Resume, Profile и другие
    content/ru.ts              русский контент: профиль, проекты, задания, раздел employers
    content/en.ts              тот же контент на английском
    resume.ts                  resumeRu и resumeEn для страницы резюме
  components/
    AppLayout.tsx              каркас: сайдбар, шапка, переключатели темы и языка
    SideNav.tsx                меню с разделами и вложенными пунктами
    CaseDetail.tsx             общая разметка страницы проекта и тестового задания
    ScreenshotGallery.tsx      галерея скриншотов и хелпер assetUrl для путей из public/
    ProjectCard.tsx            карточка проекта или задания
    PageHeader.tsx             заголовок страницы с надзаголовком и подзаголовком
    StackTags.tsx              список технологий тегами
  pages/
    HomePage.tsx               главная
    ProjectsPage.tsx           список проектов
    ProjectDetailPage.tsx      страница проекта
    EmployersPage.tsx          раздел «Работодателям»
    ResumePage.tsx             резюме, скачивание PDF и печать
    TasksPage.tsx              список тестовых заданий
    TaskDetailPage.tsx         страница тестового задания
    AboutPage.tsx              «Обо мне»
    ContactsPage.tsx           «Контакты»
    NotFoundPage.tsx           страница 404
  styles/
    global.css                 переменные тем, каркас, общие блоки, правила печати
    controls.css               стили кнопок, ссылок и переключателей
    employers.css              раздел «Работодателям» и вёрстка резюме
public/
  favicon.svg                  иконка сайта
  og-image.png                 картинка для превью в соцсетях (1200x630)
  photo.jpg                    фото для страницы «Обо мне»
  projects/<id>/*.webp         скриншоты проектов, по каталогу на проект
  resume/cv-ru.pdf             PDF-резюме на русском
  resume/cv-en.pdf             PDF-резюме на английском
  demos/green-api/             стенд-заглушка тестового задания (сгенерированный артефакт)
scripts/build-stand.mjs        сборка стенда GREEN-API из исходного репозитория green-api
stand/green-api/               исходник заглушки стенда и README по пересборке
.github/workflows/deploy.yml   сборка и публикация на GitHub Pages

Как добавить проект

  1. Сложите скриншоты в public/projects/<id>/, где <id> — идентификатор проекта. Формат webp, ширина до 1000 px, имена вида 01-название.webp. Конвертация из PNG:
magick вход.png -auto-orient -resize "1000x1000>" -strip -quality 82 \
  public/projects/<id>/01-название.webp
  1. Добавьте объект в массив projects в src/data/content/ru.ts со всеми полями типа Project (src/data/types.ts): id, name, tagline, summary, status, statusType, facts, features, stack, links, appUrl (если есть живая ссылка), runNote, runCommands, details, screenshots (массив { src, caption }, где src — путь от public/, например projects/<id>/01-название.webp), badge — по необходимости.

  2. Добавьте тот же объект в массив projects в src/data/content/en.ts. Английская запись обязательна: тип Content требует её наличия, без неё сборка упадёт на проверке типов.

  3. Больше ничего править не нужно: проект сам появится в меню, на главной, в списке проектов и на своей странице.

Новый раздел тестовых заданий добавляется так же — объектом в массив tasks тех же двух файлов, src/data/content/ru.ts и src/data/content/en.ts.

Смена резюме

  • Текст резюме: src/data/resume.ts, объекты resumeRu и resumeEn (опыт, образование, навыки, языки, проекты, условия работы).
  • PDF-файлы: public/resume/cv-ru.pdf и public/resume/cv-en.pdf. Имена указаны в полях pdf объектов резюме — при смене имён обновите и их.

Стенд-заглушка тестового задания

public/demos/green-api/ — собранный чат-клиент Telegram на GREEN-API. Стенд открывается на штатном экране авторизации, куда заглушка добавляет кнопку «Быстрый демо-вход»: посетителю не нужны ключи инстанса, а сам стенд открывается кнопкой «Открыть стенд» со страницы задания (поле appUrl в контенте). Заглушка отвечает только на демо-инстанс, поэтому со своими idInstance и apiTokenInstance запросы уходят в настоящий GREEN-API.

Как он собирается: npm run stand:green-api (обёртка над scripts/build-stand.mjs) копирует исходный репозиторий во временный каталог, подставляет stand/green-api/mock-green-api.js в public/ приложения, собирает его через npx vite build --base=./ (относительные пути к ассетам, без правки vite.config.ts) и кладёт результат в public/demos/green-api/. Исходный репозиторий при этом не изменяется: он только читается.

GREEN_API_SRC=/path/to/green-api npm run stand:green-api

Заглушка оборачивает window.fetch и отвечает на методы GREEN-API (getStateInstance, checkAccount, sendMessage, длинный поллинг receiveNotification и остальные) заранее подготовленными данными, включая автоответ собеседника. Перехват включается только для демо-инстанса — он определяется по адресу запроса /waInstance{id}/{метод}/{token}, поэтому ключи посетителя уходят в настоящий API, а не подменяются. Подробности обоих режимов — в stand/green-api/README.md.

public/demos/green-api/ — сгенерированный артефакт: он перезаписывается целиком при каждой сборке и коммитится в репозиторий (CI стенд не пересобирает). Подробности, требования (Node 22+ и сеть для npm install) и отладочные флаги — в stand/green-api/README.md.

Скриншоты

Все изображения в public/projects — реальные скриншоты приложений, а не макеты. FormEngine, «Мой Контракт» и чат-клиент GREEN-API взяты из репозиториев проектов и их e2e-снапшотов Playwright; дашборды AI Mirror и Universal Job Applier сняты локально в headless Chromium. Исходники приведены к webp с шириной до 1000 px.

Контакты

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages