The Bee Keeper, PlovdivThe Bee Keeper, Пловдив
A family beekeeper selling raw honey, pollen and propolis in small batches needed more than a social page. We built a Bulgarian-language storefront, a content site for recipes and beekeeping tips, and an admin panel the owner runs himself, with no online payment and no monthly platform fees.
Семеен пчелар, който продава суров мед, прашец и прополис на малки партиди, имаше нужда от повече от страница в социалните мрежи. Изградихме онлайн магазин на български, сайт със съдържание за рецепти и пчеларски съвети и админ панел, който собственикът управлява сам, без онлайн плащане и без месечни такси за платформа.


The business sells directly: people call, agree a jar and a pickup. The site had to fit that habit rather than replace it with a checkout the owner would have to support.
So the shop collects an order request. Customers build a basket, leave contact details, and the beekeeper phones back to confirm. That one decision removed a payment provider, webhooks and checkout sessions from the project, and it shaped most of the architecture.
Бизнесът продава директно: хората се обаждат и се уговарят за буркан и взимане. Сайтът трябваше да пасне на този навик, вместо да го замени с плащане онлайн, което собственикът би трябвало да поддържа.
Затова магазинът събира заявка за поръчка. Клиентът подрежда кошницата си, оставя данни за контакт, а пчеларят се обажда, за да потвърди. Това едно решение премахна платежния доставчик, webhooks и сесиите за плащане от проекта и определи голяма част от архитектурата.
The hexagon runs through the whole site: product cards, the honeycomb listing grid, icons and the orbit on the homepage. Colour comes from the product itself. Cream wax, dark comb, and two honey tones for accents.
Шестоъгълникът минава през целия сайт: продуктовите карти, решетката като пчелна пита, иконите и орбитата на началната страница. Цветовете идват от самия продукт: кремав восък, тъмна пита и два медени тона за акцент.
Playfair Display carries the headings with an italic accent word; Inter handles running text in Cyrillic. Prices are published on every card.
Заглавията са в Playfair Display с една дума в курсив за акцент, а основният текст на кирилица е в Inter. Цената е видима на всяка карта.

The browser's prices are discarded. The order route re-reads every product from Firestore, rejects out-of-stock items by name, and computes the total itself.
Цените от браузъра се игнорират. Сървърът прочита всеки продукт наново от Firestore, отхвърля изчерпаните по име и сам изчислява сумата.
The order is saved first, then the owner is emailed. If SMTP fails the customer still sees success, so nobody submits the same order twice.
Поръчката първо се записва, след това собственикът получава имейл. Ако SMTP се провали, клиентът пак вижда успех и не изпраща същата поръчка два пъти.
Blog, recipes, tips and product descriptions share one Tiptap editor with image, gallery, video and call-to-action blocks. Output is sanitised against an allowlist before render.
Блогът, рецептите, съветите и описанията на продукти ползват един редактор Tiptap с блокове за снимка, галерия, видео и призив за действие. Съдържанието се почиства по списък с разрешени елементи преди показване.
Photos appear as squares, hexagons and wide banners. A focal-point picker lets the owner drag the point that must stay in frame, and every shape honours it.
Снимките се показват като квадрати, шестоъгълници и широки банери. Собственикът избира с плъзгане точката, която трябва да остане в кадър, и всяка форма я спазва.
Titles are transliterated with the official Bulgarian system, so Мед с орехи becomes a clean slug. Slugs freeze on creation so shared links keep working.
Заглавията се транслитерират по официалната българска система, така че Мед с орехи става чист адрес. Адресът се фиксира при създаване и споделените връзки не се чупят.
Firestore and Storage rules require a custom admin claim for every write. Public visitors cannot create or delete orders at all.
Правилата на Firestore и Storage изискват admin права за всеки запис. Посетителите изобщо не могат да създават или трият поръчки директно.
Next.js 16 App Router, mostly server components, with listing pages regenerated every 60 seconds. There is no separate backend: one API route handles orders.
Next.js 16 App Router, предимно сървърни компоненти, а страниците със списъци се обновяват на всеки 60 секунди. Няма отделен бекенд: един API маршрут обработва поръчките.