Yande Gadgets
A bespoke operations app for a second-hand electronics shop in Accra — replacing notebook stock, shipments and reports with one Laravel workspace.
2020
- Client
- Yande Gadgets, Accra
- Type
- Bespoke operations web app
- Stack
- Laravel, PHP, MySQL, Bootstrap 4
- Team
- Sole designer and developer









Walkthrough
How the product works
A recorded pass through the live student build — stock, shipments, requests and reports.
Beyond a shop website
The work was the business process, not the storefront.
Yande Gadgets had been trading since 2011. Growth stalled because buying, shipping, selling and reporting still lived in a notebook.
Initial proposal
Put the shop online so customers in Accra could find the business.
Discovery
Observation in October 2019 showed the harder problem: purchases, shipments and sales were handwritten, reports missed expenses, and customer requests had been abandoned because people changed their minds after stock was already bought.
Product response
A role-based Laravel app that recorded each unique second-hand item, confirmed shipments, took a deposit on requests, and generated the statements the owner actually used to make buying decisions.
Mapping the reality.
Ten iterations around one shop floor.
Built through Agile sprints with the owner testing each pass. Adobe XD first, then Bootstrap 4 on Laravel.

Problem
The owner, two store staff, suppliers and customers all needed the system, but not the same screens. A single login would have exposed reports and wage data to the shop floor.
Solution
Laravel auth plus Gates. Admin runs products, shipments, suppliers and reports. Staff confirm receipts and record in-store sales. Suppliers upload stock they want to sell. Customers browse received items and request what is not on the shelf.
Before
- Verbal instructions to staff
- No audit of who did what
- Suppliers contacted off-system
After
- Role-gated navigation
- Admin settings for users and roles
- Login and registration with CSRF protection
Problem
Stock lived in a notebook. Two iPhones from the same supplier were never the same object: different scratches, different faults. Treating them as quantity-on-hand would have hidden the thing the owner actually needed to see.
Solution
A product record per item: cost, selling price, type, supplier, purchase date, condition notes, thumbnail and gallery. Featured and category filters on the shop list. Quantity was deliberately left in the backlog.
Before
- Handwritten purchase notes
- Condition remembered, not stored
- No reliable photo of the actual unit
After
- One record per unit
- Condition taxonomy with explanations
- Thumbnail and gallery on the product
Problem
There was no confirmation that a bought item had left the UK or arrived in Ghana. Loss in transit was invisible, and the shop could not tell customers what was actually on the floor.
Solution
Admin adds products to a shipment, records the courier and cost, then staff receive a persistent notification until they confirm receipt. Customers only see items that have been shipped and received. Sold items drop off the public list.
Before
- No shipment confirmation
- Stock assumed available when it was not
- Staff unaware a consignment was incoming
After
- Shipment builder with save and remove
- Staff notification until confirmed
- Received / shipped / sold states on each item
Problem
Ghana retail means negotiation. The owner would not take online checkout because the customer still had to collect in person. Sales were written down after the fact, in mixed GBP and cedi, which made the notebook totals unreliable.
Solution
Staff record the purchase against the product. The sold price cannot fall below 70% of the converted Ghana cedi value — the limit the owner set. A settings-controlled conversion rate shows GBP and GHS on the product page.
Before
- Sales written in the notebook after the fact
- Mixed GBP and cedi in the same page
- No enforced discount floor
After
- In-store purchase form for staff
- 70% floor on the converted price
- Admin-editable GBP to GHS rate
Problem
Requests used to be a unique selling point, then they stopped. People asked for a product, the owner bought and shipped it, and the customer changed their mind. That wasted the investment.
Solution
A request form for product, type, condition and notes, with a Stripe deposit in GBP. Admins are notified. Once the unit is found it is pulled into the main catalogue and the customer is told. Testers later called this the feature competitors did not have.
Before
- Informal requests, then abandoned
- Stock bought on a verbal maybe
- No payment until the customer arrived
After
- Structured request form
- Stripe deposit on the request
- Acquire-and-notify flow for admin
Problem
Weekly expense notes missed rent, wages and other liabilities. The owner thought those pages were a performance view. They were not — and buying decisions followed the wrong totals.
Solution
Admin records transactions and staff wages. Reports pull sales, shipments, purchases and wages into an income statement, a balance sheet, and CanvasJS graphs for sign-ups and sales over six months. Wage windows that overlap the selected period are clipped so the liability is not double-counted.
Before
- Paper sales reports
- Missing rent and wages in the totals
- No period filter
After
- Multi-row expense entry
- Generated statements for a chosen period
- Sales and sign-up charts
04 / Design deep-dives
Three problems that were not a website
The brief looked like ecommerce. The work that mattered was inventory identity, demand without waste, and numbers the owner could trust.
From a notebook line to one physical unit
Problem
Second-hand stock cannot be SKU quantity. Two phones from the same supplier arrived with different faults. The owner already treated them as Cash Converters would — separate objects — and asked for the app to do the same.
Contribution
I interviewed the owner, watched how purchases were written down, and designed the product model around condition, supplier and photos instead of a quantity field.
Constraints
- The owner was not technical, so forms needed an explanation column, including what each condition meant.
- Quantity was explicitly parked: useful later, a distraction in 2020.
One row, one object
A product record is a physical unit. Duplicating a listing is cheaper than hiding a scratch behind a stock count.
Condition as data, not a note in the margin
A conditions table with details and explanations sits next to the form, so staff pick a type instead of inventing wording.
Photos on the unit, not the model
Thumbnail plus gallery belong to that item, because the next iPhone in the same shipment will not look the same.
Catalogue cards. Sold and shipped are states on the unit, not stock remaining.
Outcome
Shipped. The catalogue the shop actually used was a list of unique units with shipped, received and sold states — not a warehouse quantity screen.
05 / Design to code
Where building protected the design
Adobe XD set the Ghana-flag chrome — yellow bar, green footer, role-coloured dashboards. Laravel MVC, Blade and Bootstrap 4 were how those screens stayed honest once staff, suppliers and a Stripe charge were on the same host.
Gates instead of hidden buttons
NFR work said only admin ships, only staff confirm receipt, only admin sees reports. Those rules live in Laravel Gates and middleware, not in CSS. A staff login cannot open the statements by guessing a URL.
Charge the deposit where the money actually clears
The request is a Ghana shop-floor idea. The payment ran through Stripe in GBP because that is what would actually take a card in 2020. Metadata on the charge keeps product, type and condition attached to the payment, not just a number.
Show both currencies, enforce one floor
Selling price is stored in GBP. The product page multiplies by an admin-set rate for GHS. The 30% negotiation limit is checked against the converted value, then written back, so a cedi bargain cannot silently wipe the sterling cost.
- Laravel
- PHP
- MySQL
- Bootstrap 4
- Blade
- JavaScript
- CanvasJS
- Stripe
- Adobe XD
06 / Outcome and status
Where the product stood
The 2019–20 final-year build shipped through ten iterations and was tested with the owner, a staff member, a supplier and a customer. Quantity search, receipt photos and colour-coded statement alerts were left as follow-ons.
This has improved the process of the business, but also, it has confirmed that my lack of investment into technology has made me fall behind in competition, if I invested into doing something like this earlier, I would have been in a better position than today. The staff members now understand their fundamental responsibility and their obligations, especially now I can see whether they have done what I have asked them to do. But overall, the business process has improved.
Evidence
- Customer testing called product requests a unique selling point competitors did not have — the same request habit the owner had previously stopped.
- The owner described the generated report as the icing on the cake: buying decisions from statements he no longer had to fill in.
What's next
The backlog the owner agreed was quantity on products, staff photo confirmation on receipt, product search, and visual flags when a statement goes negative.
Reflection
The lesson was to treat the family shop as a real operations problem, not a portfolio storefront. Agile with the owner in the loop meant requests-and-deposits could still land as a priority once interviews proved the old version lost money. If I did it again I would add search and receipt photos before calling the shop-floor loop finished.
