All projects

Client work · 2024 – present Project 2 of 20

Cukrárna Laušman

Website, orders and ratings for a pastry shop with a tradition going back to 1791.

Visit the site

Verified site status: Up, 735 ms response,

Homepage of Cukrárna Laušman with a photo of the shop and the label Since 1791

At a glance

Role
Design, development and operations
Period
2024 – present
Status
Live
Technologies
10 technologies
Client
Cukrárna Laušman

Cukrárna Laušman in Miletín bakes gingerbread and cakes from family recipes. I wrote the first version of the website in 2024; in 2026 I rebuilt it on Nette and added an admin for products, texts, orders and reviews. The catalogue did not get locked away in a database, though: it lives in a Google spreadsheet that can be edited even without the admin.

Why it is technically interesting

  • The spreadsheet as the single source of truth. Products and prices are read from Google Sheets, and the admin writes back to them through the API. A deleted product is only emptied and switched off so that rows do not shift, and assigning photos in bulk rewrites a single column instead of the whole row.
  • Price list and gallery without manual work. The PDF price list is generated from the spreadsheet with one click, and a console command downloads gallery photos from a shared Google Drive folder, thumbnails included.
  • Orders through links. Every company or event gets its own address for the order form. A switched-off link says it is closed instead of showing an error, and even a deleted link stays in the order history and in the CSV export.
  • Ratings after hand-over. As soon as an order is marked as handed over, the customer gets an email with stars, and a click pre-fills the rating. Each item is rated separately, and the admin works out an average for every product across orders.

Obstacles and how I solved them

  • Emails failed only on the web. The production PHP-FPM lacks the iconv extension, which Nette Mail needs for headers with accented characters, while the command-line PHP has it – so tests from the shell passed and the site failed. I added a replacement built on mbstring that steps aside as soon as the extension is installed, and I test with the same binary the site runs on.
  • Accents in the PDF. FPDF needs the Windows-1250 encoding, but on some PHP builds mbstring swaps it for ISO-8859-2 and "š" turns into "ą". The price list therefore converts characters with its own table.
  • A schema without migrations. The SQLite database brings itself up to date on start and adds missing columns based on PRAGMA table_info. The catch was the Nette Database cache, which did not know about a new table and claimed it did not exist. The initialiser now rebuilds the cache whenever the schema changes.

What you don't see

  • Statistics without third-party tools. Visits, product clicks and price list downloads are measured by a small system of my own, with charts in the admin. The IP address is only stored with consent.
  • Ratings without accounts. The rating link carries a random token, an order can be rated only once, and a rating becomes a review on the site only with the customer's consent and after approval in the admin.
  • History that does not get lost. Orders keep the link they came through, so they stay readable after the link is deleted and can be exported to CSV at any time.

Technology

  • Nette 3.2 and Latte – forms with CSRF protection and templates that escape output on their own.
  • SQLite – orders, ratings, texts and statistics; the catalogue stays in the spreadsheet.
  • Google Sheets API and Google Drive API – products, prices and gallery photos.
  • FPDF – a PDF price list with Czech accents.
  • Tailwind CSS, GSAP and Lenis – smooth scrolling and scroll-triggered animations.
  • Chart.js – visitor charts in the admin.
  • Symfony Console – the gallery sync command.

Built with

  • PHP 8.2
  • Nette
  • SQLite
  • Google Sheets API
  • Latte
  • Google Drive API
  • FPDF
  • Tailwind CSS
  • GSAP
  • Chart.js

Keyboard shortcuts.

Keyboard shortcuts for this site. They stay quiet while you type into a form.

This site

?
This help
g
12-column grid, components and page metrics
d
Appearance: system, light, dark, Linkin Park
Ctrl P
Print the CV instead of the website
Esc
Close the dialog or the grid

The blue dot after the name can be grabbed and thrown.

Linkin Park

l setlist lp
The setlist, songs by album
papercut
The page tears like paper
numb
The site goes numb for a few seconds
faint
The page faints and comes round
meteora
A meteor shower and a direct hit on the dot after the name
fromzero emily
The site fades down to zero and is reborn, with thanks to Emily Armstrong
concert koncert
Concert: the site runs through the colours of every album
castleofglass
The page turns to glass, cracks and shatters
iridescent
Headings and dots shimmer in rainbow colours
breakingthehabit
Whatever is on screen falls apart and snaps back
intheend
End credits, like at the cinema
victim morethevictim
The site breaks up in a glitch and stays distorted (until a reload, another word or Esc)
finalmasquerade
A masquerade mask over the whole site, the camera flies through an eye
lost
Off to the 404 page

Type the words anywhere outside the form; case and spaces do not matter. With reduced motion you get a short note instead.

On a phone, five taps on the blue dot after the name open the setlist.