ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
Полностью переписанный фронтенд платформы: курсы, Marketplace, подписки, сообщество, личный кабинет и админ-панель Studio. Бизнес-логика и контент перенесены из прежней версии, интерфейс собран с нуля. Стек: Next.js 16 (App Router, Turbopack) · TypeScript · Tailwind v4 · существующий Express API. Вид: тёмная кинематографичная база, светящийся оранжевый #FF7A1A, слой движения на CSS + IntersectionObserver. Нужен работающий API прежнего проекта на http://localhost:3001:查看完整 README ↗
Полностью переписанный фронтенд платформы: курсы, Marketplace, подписки, сообщество, личный кабинет и админ-панель Studio. Бизнес-логика и контент перенесены из прежней версии, интерфейс собран с нуля.
Стек: Next.js 16 (App Router, Turbopack) · TypeScript · Tailwind v4 · существующий Express API.
Вид: тёмная кинематографичная база, светящийся оранжевый #FF7A1A, слой движения на CSS + IntersectionObserver.
npm install
npm run dev # http://localhost:4000
Нужен работающий API прежнего проекта на http://localhost:3001:
cd ~/Desktop/Insider_academy/Insider_academy && npm run dev:server
| Переменная | По умолчанию | Зачем |
|---|---|---|
API_ORIGIN | http://localhost:3001 | Адрес Express API |
SITE_URL | продакшн-домен | Канонические ссылки, sitemap, реферальные |
R2_* | пусто | Cloudflare R2 с видео уроков — см. .env.example |
Без R2_* урок, у которого в контенте лежит ключ объекта, показывает заглушку
«видео скоро». Ролики по пути /videos/… работают без всякой настройки.
Прочие команды: npm run build, npm start, npm run typecheck.
app/
[locale]/ ru | ukr | en — единственный корневой layout
(site)/ публичная витрина: главная, learn, store, plans, community, legal
(auth)/ вход, регистрация, подтверждение, восстановление
app/ личный кабинет (AppShell: сайдбар + нижняя навигация)
study/ учебное пространство — отдельная оболочка без кабинета
studio/ админ-панель за отдельным паролем
api/[...path]/ прокси к Express с подстановкой Bearer-токена
components/
primitives/ кнопки, поля, диалоги, тосты, таблицы, скелетоны — всё своё
layout/ catalog/ store/ study/ app/ studio/ community/ plans/
content/
data/*.json контент, выгруженный из прежнего проекта (1 МБ)
*.ts типизированный доступ к нему
lib/
api/ серверный слой данных, один вызов на запрос (React cache)
auth/ httpOnly-cookie сессии + server actions
i18n/ словари ru / ukr / en, форматирование чисел и дат
proxy.ts локали, редиректы со старых URL
Сессия в httpOnly-cookie. Прежний клиент держал JWT в localStorage, где его
может прочитать любой внедрённый скрипт. Теперь токен живёт в httpOnly-cookie,
а клиентские запросы идут через /api/[...path] — прокси сам подставляет
Authorization. Токен ни разу не попадает в JavaScript.
Один резолвер доступа. lib/api/session.ts → getAccess() отвечает на вопрос
«можно ли открыть это». Раньше правила были размазаны по компонентам — из-за чего
аккаунт с меткой All Access упирался в пейволл внутри плеера.
Ошибки не протекают. lib/api/http.ts превращает любой ответ в ApiError
со стабильным кодом; UI подставляет свой текст. Строка вроде Not found больше
не может оказаться на экране рядом с полем промокода.
Доступность продаж проверяется заранее. getCheckoutStatus() спрашивает API
о режиме предзапуска до того, как пользователь начал выбирать. Закрытая касса
показывается на карточке, а не на последнем шаге.
Цены — из одного источника. Стоимости берутся из content/plans.ts и каталога;
в разметке нет вбитых руками сумм, поэтому главная и страница подписок не могут
разойтись.
Фильтры живут в URL. Каталог и магазин фильтруются на сервере по search params —
отфильтрованную полку можно отправить ссылкой. Компоненты, читающие useSearchParams,
обёрнуты в Suspense: без этого страница выпадает из пререндера и не гидрируется.
Страница как последовательность глав. Длинная страница не один бесконечный
лист, а смена грунта: chapter + ch-paper / ch-ink / ch-tint. Глава
объявляет фон, а токены следуют за ней — карточки, линии и текст внутри
остаются верными без ручных переопределений. Отсюда тёмные блоки на светлой
теме и тёплый оранжевый разворот там, где речь о деньгах.
Движение без библиотек. components/motion/ — Reveal / RevealGroup
(выход по скроллу с каскадом), Headline (заголовок набирается по словам или
по строкам), Wipe (кадр открывается, а не проявляется), Parallax,
ScrollRail (линия заполняется по мере чтения раздела), Spotlight и
Magnetic (курсорные), Journey, Marquee. Общий наблюдатель — useInView.
Скрытое состояние живёт в CSS, скрипт только снимает его, поэтому ничего не
остаётся невидимым, если JS задержался. prefers-reduced-motion выключает всё
разом.
Две ловушки, на которые уже наступили: IntersectionObserver учитывает
clip-path, поэтому наблюдать надо за внешним элементом, а обрезать внутренний;
а элемент с незавершённой transform-анимацией становится содержащим блоком для
position: fixed внутри — из-за этого переход страницы (.animate-page) идёт
без fill-mode.
Тёмная тема — решение, а не системная настройка. :root тёмный всегда;
светлая включается только атрибутом data-theme="light" от переключателя.
Кинематографичные блоки на светлой теме сохраняют свой фон через класс .on-dark.
Локаль контента честная. У части статей поле title написано по-украински.
detectLang() определяет язык по буквам, которых нет во втором алфавите; русская
локаль показывает только русские материалы, остальные — отдельным блоком с бейджем.
ADMIN_PASSWORD,
пароля у меня не было. Интерфейс построен по контрактам /api/admin/*;
первый вход стоит пройти вместе.PUT /admin/courses
и PUT /admin/blog не сделаны./api/marketplace/me/entitlements отвечает ошибкой no such column: p.title —
баг на стороне API, из-за него не видно купленных товаров.content/data/legalEntity.json): пока в полях
стоит TODO:, юридические страницы показывают предупреждение, а касса — нет.