Демо-проект
Дашборд барбершопа: BROMID
Сетка «мастер × время», перенос записи перетаскиванием, лояльность и аналитика студии.
разработка · Next.js 15 · TypeScript · Tailwind · Zustand

Задача
BROMID - барбершоп в Екатеринбурге: четыре мастера, четыре кресла, работа с 10:00 до 22:00. Демо-проект: студия вымышленная, задача типовая для ниши. По легенде клиенты записываются через Telegram-бота, но за стойкой всё равно сидит администратор, и его смена состоит из одних и тех же вопросов: кто сейчас в кресле, кто придёт вечером, кто не пришёл, можно ли сдвинуть запись на полчаса, чтобы влезла ещё одна. Пока это решается в тетради или в общем чате, каждый вопрос стоит минуты и звонка. Панель должна отвечать с одного взгляда, а запись переноситься движением мыши, а не перепиской.
Решение
Пять экранов - расписание, записи, клиенты, мастера, аналитика - плюс вход, дисклеймер и страница 404: восемь маршрутов статического экспорта. Бэкенда нет, всё считается в браузере.
- Расписание - сетка «мастер × время» на день и «день × время» на неделю по выбранному мастеру. Рабочее окно 10:00-22:00, шаг 15 минут, текущий момент отмечен линией.
- Перенос записи перетаскиванием: за курсором идёт призрак, прилипая к четверти часа, а сама плитка гаснет и остаётся на месте до отпускания. Свободный слот призрак обводит горчичной рамкой, недопустимый - красным пунктиром с названием причины: «Слот занят», «Слот уже прошёл», «Слот вне рабочих часов», «Дата вне окна данных». Отпустил над занятым - запись осталась на месте, в уведомлении написано почему. Esc отменяет перенос прямо во время движения.
- В сетке дня перетаскивание меняет мастера и время, в сетке недели - день и время.
- Смена статуса и перенос подтверждаются уведомлением с кнопкой «Отменить действие»: один шаг назад, пока уведомление на экране. Отказ в переносе тоже даёт уведомление, но откатывать в нём нечего.
- Записи - список с фильтрами по периоду, мастеру и статусу, поиском и постраничной выдачей по 25 строк. Карточка записи держит историю статуса, цену визита и форму переноса на другого мастера, другую дату или другое время.
- Клиенты - справочник с сегментами «постоянные», «новые», «близко к бесплатной», «записаны наперёд», карточка с историей визитов и шкалой лояльности: каждая шестая стрижка бесплатно.
- Мастера и аналитика - загрузка кресел, выручка, средний чек, доля неявок и отмен, спрос на услуги, пик по часам, графики по дням.
Детали, которые легко не заметить
- Данные детерминированы: собственный генератор случайных чисел с фиксированным зерном, «сейчас» - константа, а не показания часов. Каждый запуск даёт ту же самую картинку. Тест держит sha256-отпечаток датасета: молча разъехаться со скриншотами генератор не сможет.
- Спрос смоделирован, а не рассыпан наугад: вечер плотнее дня, выходные плотнее будней, дальний край будущего полупустой - записи туда ещё не пришли. Заполняемость получается 57%: тест держит её в коридоре 55-65%, а точное значение фиксирует тот же отпечаток датасета.
- Отменённая запись слот не занимает и рисуется перечёркнутой: поверх неё можно поставить новую. Неявка слот занимает - кресло всё равно простояло. Разница между этими двумя случаями и есть половина смысла статусов.
- Лояльность пересчитывается сама: отметил клиенту «пришёл», и если это была шестая зачётная стрижка, цена обнулилась без ручной правки. Борода, камуфляж и воск счётчик не двигают.
- Шесть зачётных стрижек в окно данных не помещаются: за 45 дней у клиента в среднем три записи. Поэтому у большинства клиентов есть история до окна - иначе шкала лояльности стояла бы пустой на всех экранах. У 82 клиентов из 577 такой истории нет, и панель прямо подписывает их новичками.
- Статус не передаётся одним цветом: на плитке рядом с цветной полосой стоит иконка, отменённая запись ещё и перечёркнута, а словом статус подписан в легенде над сеткой и в бейджах списков. На этот экран смотрят по восемь часов подряд.
- Вход демонстрационный и честно об этом говорит: логин и пароль напечатаны на форме и уже подставлены в поля, проверка в браузере, сессия в sessionStorage. Это закрытый вход, а не настоящая защита: роль в панели одна.
- Гигиена демо: плашка о демонстрационном характере в сайдбаре, отдельная страница дисклеймера, noindex в метаданных и X-Robots-Tag в заголовках выкладки.
- Мобильной раскладки нет осознанно: сетка расписания на 375px нечитаема. Брейкпоинты 1440 / 1024 / 768.
Цифры
Окно данных - 45 дней, в нём 1 733 записи и 577 клиентов. С витриной студии совпадают справочники: те же четыре мастера с теми же специализациями, тот же прайс из восьми позиций по тем же ценам, те же часы работы и то же правило «каждая шестая стрижка бесплатно». 135 автотестов, из них 17 на перенос записи, и сценарий из 32 проверок, который проходит панель как администратор: вход, смена статуса, откат, перенос перетаскиванием, отказ на занятом слоте, выход.
Скриншоты




