← All Work
Case Study · App Development · UX/UI Design

Studio 57 POS
Developer Case Study

I designed, built and now maintain the point-of-sale app that runs Studio 57 Nail Bar & Spa from an iPad at the front desk. This is the story from version 1, through what broke once the salon depended on it every day, to the redesign that fixes it.

Client
Studio 57 Nail Bar & Spa (nail salon, 8 stylists)
My role
UX/UI designer and developer: research, design, front end, back end, release
Platform
iPad web app, opened from a home-screen icon
Stack
React, TypeScript, Vite, Tailwind CSS, Google Apps Script, Google Sheets, Netlify
This round
Oct 19 to Oct 23, 2026: data recovery, redesign, build and testing
Users
Front-desk staff aged 40 to 60, and the owner as admin
Version 1 login: black lock screen with logo and keypad
Version 1 login: black lock screen with logo and keypad
Version 1 employee POS: one ticket, stylist chosen from dropdowns
Version 1 employee POS: one ticket, stylist chosen from dropdowns
Version 1 admin dashboard: calendar, six totals and the audit log
Version 1 admin dashboard: calendar, six totals and the audit log
Version 1Version 1 on an upright iPad: tabs run into each other and the table is cut off
Version 1 on an upright iPad: tabs run into each other and the table is cut off
01 — Version 1

What I built
and launched

The first version replaced paper tickets with an iPad app: staff log in with a PIN, ring up services, and every sale is sent to a Google Sheet. I designed it in Figma, built it in React, and connected it to a Google Apps Script that stores the data in Google Sheets.

  • PIN login. A black lock screen with the salon’s logo and a large keypad. Staff and admin each have a 4-digit code.
  • Employee POS. Service menu on the left, live receipt on the right: pick a main stylist, add services and polish colors, choose payment and tip, then log the ticket.
  • Admin dashboard. A calendar, six daily totals and tabs for audit logs, analytics, inventory, staff, the menu and settings.

Version 1 worked well for one stylist and one client at a time. The cracks showed once the whole team used it on busy days.

02 — Real use

What happened once the salon used it every day

About four months of real use showed that the app’s biggest problem was invisible: sales had stopped reaching the Google Sheet, so the business records were incomplete. Everything else came from watching how the team actually works, several stylists and clients at the same time.

The full list is below.

What we saw at the salon

Eight problems, eight causes

What we saw at the salonWhy it happenedImpact
The Google Sheet stopped showing new salesEach day was saved in the script’s private settings, which have a size limit; it was about 80% fullThe owner asked for every transaction to date and the Sheet couldn’t provide it
Two stylists working at once got in each other’s wayThe app held only one open ticketOne stylist waited, or kept services in her head until the other checked out
Opening cash showed $200 every morningThe server sent $200 for any day not saved yet, overriding the carried-forward amountThe admin retyped it daily; when they forgot, cash totals were wrong
Monthly and quarterly reports didn’t match realityThey multiplied today’s figures instead of adding up real ticketsNo trustworthy report for any date range
A forgotten ticket stayed forgottenPast days could be viewed but not added toMissed sales never reached the books
The admin screen broke on an upright iPadThe layout assumed a wide screenTabs and cards overlapped and the table was cut off
I got locked outThe salon changed the passcodes after launchI couldn’t get in to support them
Staff struggled with small text and dropdownsThe team is in their 40s to 60sSlower checkout and more mistakes
398,640 / 500,000
bytes of the script’s private settings store were used, about 80% full
Option A · Ticket tabsTicket tabs across the top, menu on the left, receipt on the right
Ticket tabs across the top, menu on the left, receipt on the right
Option B · Staff lanesStaff sidebar with each stylist’s open clients
Staff sidebar with each stylist’s open clients
Option C · Ticket boardA board of open-ticket cards
A board of open-ticket cards
After“Who is this ticket for?” with stylist tiles and client type
“Who is this ticket for?” with stylist tiles and client type
BeforeOne ticket, stylist dropdowns
One ticket, stylist dropdowns
AfterOpen-ticket tabs, pink added services and the receipt
Open-ticket tabs, pink added services and the receipt
After“Who did this service?” picker
“Who did this service?” picker
AfterCheckout with payment, discount and tip
Checkout with payment, discount and tip
After“Transaction Logged” with “Saved to Google Sheet ✓”
“Transaction Logged” with “Saved to Google Sheet ✓”
BeforeThe audit log as one table
The audit log as one table
AfterAudit logs by stylist, one ticket open for editing
Audit logs by stylist, one ticket open for editing
AfterA past day with an added ticket marked “Added later by admin”
A past day with an added ticket marked “Added later by admin”
Before“Close Out Register Drawer?” with only Cancel and Proceed
“Close Out Register Drawer?” with only Cancel and Proceed
AfterClose register with a cash count and tomorrow’s opening cash
Close register with a cash count and tomorrow’s opening cash
AfterOpening cash carried forward, with drawer history
Opening cash carried forward, with drawer history
BeforeAnalytics with popular services only
Analytics with popular services only
AfterReports tab with date range, totals and breakdowns
Reports tab with date range, totals and breakdowns
AfterAnalytics with client types
Analytics with client types
AfterEmail a report for any date range
Email a report for any date range
BeforeVersion 1 upright: tabs overlap
Version 1 upright: tabs overlap
AfterAdmin on an upright iPad
Admin on an upright iPad
AfterThe ticket screen in Dark mode
The ticket screen in Dark mode
43 checks
23 end-to-end checks and 20 server tests passed on a copy of the real records
823 tickets
recovered across 85 days, none lost or duplicated, and no storage limit left to hit
03 — The urgent fix

Solving the missing
transactions

I fixed the storage before touching the design, so no sale could be lost while the salon kept working.

  1. Found the cause. I read the whole app and the Google script, then compared the iPad’s records with the Sheet day by day. The private settings store was 398,640 of about 500,000 bytes full.
  2. Saved a copy of everything. A one-time script exported all 822 stored tickets from 84 days into the Sheet.
  3. Moved storage into the spreadsheet. I rewrote the script to keep each day in a Sheet tab, plus a readable Tickets tab with one row per ticket. Big days are split across cells, so there’s no size limit anymore. The app’s screens didn’t change, so staff never noticed.
  4. Checked it in real use. 85 days and 823 tickets moved, and that afternoon’s real checkouts landed straight in the Tickets tab.
  5. Added a safety net. A “Backup transactions” screen lets the admin compare the iPad with the Sheet and send only the missing tickets, never duplicates.

That fixed the records. The rest of the list needed a redesign.

04 — Redesign

First ideas,
and why one won

The core question was how several stylists can each keep a ticket open without crowding the screen. I sketched three answers, in a new visual style at first, and showed them to the owner.

The owner picked A and asked for B’s sense of who is busy. Two pieces of feedback then shaped everything after:

Keep the fonts and colors the same.The staff already knew the app, so the final screens use version 1’s system font, grays, pink and green, and keep familiar pieces such as the receipt rows, the amber massage control and the discount box.
Make it as big and simple as it can be.Big tiles, one decision per screen, and strong color for whatever is selected.
05.1 — What changed

Starting a ticket

Why it changed

In version 1 the stylist was a dropdown inside the receipt, easy to skip or pick wrong, and there was no record of what kind of client it was. The owner also wanted to know how many clients are walk-ins, regulars or appointments.

What changed

A first screen asks “Who is this ticket for?” with big stylist tiles and a required client type. Nothing is pre-selected, so no one can tap straight through. The client’s name is optional, and “View Tickets” skips straight to the open tickets.

05.2 — What changed

Several clients at once

Why it changed

With one ticket at a time, a second stylist had to wait or remember her services.

What changed

Open tickets sit as tabs across the top, with a count badge. The active tab turns pink so it’s clear whose client you’re on. Services added turn pink with “✓ ADDED”, and each ticket saves itself on the iPad, so nothing is lost if the app closes. Tips and payment wait until checkout, because services get added while the client is still in the chair.

05.3 — What changed

Two stylists, one client

Why it changed

Clients often get a manicure from one stylist and a pedicure from another, and the stylist dropdowns were hard to use.

What changed

Each service has a “Done by ▾” button that opens the same big stylist tiles. The ticket becomes Multi-Staff, and tips and commission still split the way they always did.

05.4 — What changed

Checking out and
knowing it saved

Why it changed

Version 1 put everything on one long panel and never confirmed the sale reached the Sheet, which is how the missing records went unnoticed.

What changed

“Ready to check out” opens a short checkout (payment, discount, tip, LOG TICKET), then a confirm step. The receipt says “Saved to Google Sheet ✓” only once the Sheet has the ticket. Until then the ticket waits on the iPad and is sent again if needed.

05.5 — What changed

Audit logs and
fixing mistakes

Why it changed

The audit log was one long table of every ticket. To fix one stylist’s ticket, the owner had to scan everyone’s, and editing meant typing into small cells.

What changed

A tab per stylist with a ticket count, newest ticket first. Tapping a ticket opens it with the same receipt rows staff use, and saving changes only that one ticket, so an edit can never wipe tickets another device saved.

05.6 — What changed

Adding a ticket someone forgot

Why it changed

On busy days a sale sometimes wasn’t logged, and past days couldn’t be changed.

What changed

Pick any past day on the calendar and tap “Add a missed ticket”. It saves to that day and the Sheet, marked “Added later by admin” so it’s easy to audit.

05.7 — What changed

Opening cash and
closing the register

Why it changed

Opening cash reset to $200 every morning, and closing was a two-button popup that never asked how much cash was actually in the drawer.

What changed

Closing now asks for the counted cash, shows the difference from what’s expected, and says “$247.00 tomorrow’s opening cash”. The next morning starts with that amount automatically, with a drawer history to check against. A new Cash in Hand card shows the day’s own cash: cash sales minus card tips and commissions paid out of the drawer.

05.8 — What changed

Real reports

Why it changed

The owner asked for every transaction to date, and the old monthly figures were estimates.

What changed

A Reports tab with any date range, real totals, payment methods, stylists, services and every transaction, plus Download and Email Report. Analytics adds Walk-in, Regular and Appointment by day, month and year.

05.9 — What changed

iPad upright, Dark mode and
access

Why it changed

The iPad is sometimes stood upright, where version 1 overlapped. The client also asked for a dark mode. And after the salon changed its passcodes, I had no way to get in to support them.

What changed

On an upright iPad the calendar folds into a date bar and the tabs sit in two rows. A Light and Dark switch sits next to Font Size, and both are remembered. A developer PIN is kept only in the server’s private settings, never in the app or the Sheet.

06 — Testing

Before it goes back
into the salon

The new version had to pass one test above all: every past and present transaction stays exactly as it was.

  • Tested on the real records. I ran the new app in a test browser against a simulated Google script loaded with the salon’s real 87 days and 836 tickets.
  • Walked through a full day. Two tickets open at once, the app closed and reopened, a shared ticket checked out, an admin edit, a missed ticket on a past day, reports, email, closing the register, the developer PIN, an upright iPad and Dark mode.
  • Checked the money. For example: Color Gel $35 + Lavender Spa $50 + 5 extra massage minutes ($5) = $90, tax on card $7.99, commission $5.
  • Checked nothing old moved. Every past day was identical afterwards except the one where I added a ticket on purpose, and the iPad still held every ticket.
  • Results: 23 end-to-end checks and 20 server tests passed.
  • Safe release plan. The code sits on its own branch. The server update goes first because it also works with the current app. The new app goes live after closing, with a short note to staff.
07 — Outcome

Records complete,
redesign approved

The salon’s records are complete again, and the redesign the owner approved fixes every problem found in real use.

  • One problem, one change. Each issue from the salon floor has a matching fix: open tickets, Done by, a confirmed save, missed tickets, a counted drawer, real reports, an upright layout and a developer PIN.
  • 43 checks passed on a copy of the real records before anything goes live.
What I learned

Launching is the start, not the end.

The most important problems only showed up after weeks of real use with the whole team.

Fix the data before the pixels.

The most valuable work was invisible: making sure no sale could be lost.

Design for the people at the counter.

For staff in their 40s to 60s, bigger targets, fewer choices per screen and clear feedback like “Saved ✓” mattered more than new features.

Keep what people already know.

Keeping version 1’s fonts, colors and familiar controls made a big change feel small to the staff.

To add after launch: staff feedback and any time saved at checkout, after a few weeks of use.

More work

Looking for the design side of this project? See the full Studio 57 website and booking app case studies.

← Back to all work