Skip to content

Repository files navigation

Crux

Офлайн-first PWA — интерактивный конструктор скалолазных трасс. «Красишь» зацепы на доске с фиксированной сеткой по ролям (старт / рука / нога / топ), сохраняешь трассы локально и делишься ссылкой — вся трасса закодирована прямо в URL. Бэкенда нет, всё работает на статическом хостинге.

Демо: https://arbaev.github.io/crux/

Android: скачать APK

Стек: Vue 3 + Quasar + TypeScript (strict)

архитектура с чётким разделением состояния и рендеринга, PWA с офлайн-режимом, шаринг без сервера, i18n, сборка под Android.

Возможности

  • Конструктор трасс. Тап или свайп по зацепам — «покраска» ролями: старт, рука, нога, топ (топ — всегда единственная точка). Кисть-ластик и снятие роли повторным касанием.
  • Локальное хранилище. Трассы сохраняются в браузере (IndexedDB): создание, открытие, дублирование, удаление, имя и категория сложности.
  • Системы сложности. Font, V-scale, French, цветовая и произвольная метки.
  • Шаринг без сервера. Трасса целиком кодируется в ссылку (?r=…) — получатель открывает её в режиме просмотра и может сохранить себе. Ссылка копируется в буфер одной кнопкой.
  • PWA. Устанавливается как приложение, работает офлайн (service worker), обновляется по запросу.
  • Мультиязычность. Русский и английский с автоопределением по языку браузера и запоминанием выбора.
  • Адаптивный интерфейс. Раскладка под десктоп (сайдбар) и мобильный (нижняя панель инструментов).
  • Сборка под Android (Capacitor) — опционально, помимо веба/PWA.

Технологии

Сфера Стек
Фреймворк Vue 3 (Composition API, <script setup>), Quasar v2
Сборка @quasar/app-vite v2 (Vite), TypeScript (strict)
Состояние Pinia (setup-стиль)
Хранилище IndexedDB через idb
Рендеринг доски 2D SVG (без зависимостей)
i18n vue-i18n + lang-паки Quasar
PWA Workbox (InjectManifest), service worker с prompt-on-update
Мобильное Capacitor (Android)
Тесты Vitest (unit-тесты чистых функций)

Как это устроено

Архитектурный принцип — рендерер не владеет состоянием, он его отражает:

Трасса хранится как чистые данные (роли по зацепам), не зависящие от способа отрисовки. Благодаря этому рендерер был заменён с Three.js на 2D-SVG без единой правки бизнес-логики, кодека и тестов.

Формат ссылки (контракт шаринга, v1):

v1.7x10.12S,19H,23H,67T
└┬┘ └─┬─┘ └──────┬──────┘
вер.  сетка   токены: <индекс ячейки><роль S/H/F/T>

Кодирование/декодирование — чистые функции (src/lib/routeCodec.ts), round-trip покрыт unit-тестами.

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

Требуется pnpm (другие пакетные менеджеры не использовать — есть pnpm-lock.yaml).

pnpm install                    # установка зависимостей
pnpm dev                        # dev-сервер (SPA) → http://localhost:9000/
pnpm exec quasar dev -m pwa     # dev в PWA-режиме (проверка service worker)

Сборка и проверки

pnpm build                      # прод-сборка SPA → dist/spa
pnpm exec quasar build -m pwa   # прод-сборка PWA → dist/pwa (цель деплоя)
pnpm test                       # unit-тесты (Vitest)
pnpm lint                       # ESLint
pnpm format                     # Prettier

Деплой на GitHub Pages автоматизирован через GitHub Actions (.github/workflows/deploy.yml). Сборка Android-APK описана в docs/android-build.md.

Структура проекта

src/
├── pages/         экраны: конструктор (/), мои трассы (/routes),
│                  просмотр ссылки (/view), настройки (/settings), 404
├── layouts/       MainLayout — каркас с навигацией
├── components/    BoardSvg (рендерер доски), палитра кистей, тулбары, карточка трассы…
├── composables/   useLocale (язык), useInstallPrompt (PWA)
├── stores/        Pinia: board (конфиг доски), route (трасса + персистентность)
├── lib/           чистые модули: routeCodec, db, board, grades, roles
├── router/        маршруты приложения
├── i18n/          локали en-US (мастер-схема) и ru-RU
└── types/         модель данных

Лицензия

MIT © 2026 Timur Arbaev

About

Crux is an offline-first builder for climbing-wall routes: paint holds by role on a fixed board, save them locally and share via a link — no backend required.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages