https://github.com/neofox/jeromeschaeffer-vending-machine
A simple vending machine example made for an interview
https://github.com/neofox/jeromeschaeffer-vending-machine
Last synced: 11 months ago
JSON representation
A simple vending machine example made for an interview
- Host: GitHub
- URL: https://github.com/neofox/jeromeschaeffer-vending-machine
- Owner: Neofox
- Created: 2025-08-01T06:31:41.000Z (11 months ago)
- Default Branch: master
- Last Pushed: 2025-08-01T06:33:45.000Z (11 months ago)
- Last Synced: 2025-08-01T08:54:32.308Z (11 months ago)
- Language: TypeScript
- Size: 43.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Vending Machine
A vending machine simulator built with React, TypeScript and Tailwind CSS.
This project was made as a interview exercise.
## Technology Stack and versions
- **UI**: React v19.1
- **TypeScript**: v5.8
- **Build Tool**: Vite v7
- **Runtime**: Bun v1.2
- **Styling**: Tailwind CSS v4.1
- **Testing**: Bun test runner
- **Linting**: ESLint v9
## How to Run
### Prerequisites
#### Option 1: Using Bun (Recommended)
- **Bun** v1.2.0 or higher
#### Option 2: Using Node.js/npm
- **Node.js** v22.0 or higher
- **npm** v10.0 or higher
### Installation & Setup
1. **Clone the repository**
```bash
git clone https://github.com/Neofox/jeromeschaeffer-vending-machine.git
cd jeromeschaeffer-vending-machine
```
#### Using Bun (Recommended)
2. **Install dependencies**
```bash
bun install
```
3. **Start the development server**
```bash
bun run dev
```
The application will be available at `http://localhost:5173`
#### Using Node.js/npm
2. **Install dependencies**
```bash
npm install
```
3. **Start the development server**
```bash
npm run dev
```
The application will be available at `http://localhost:5173`
### Useful Scripts
- `bun run dev` - Start development server
- `bun run build` - Build for production
- `bun run preview` - Preview production build
- `bun run test` - Run tests
## Project Structure
```text
src/
├── components/ # React components
├── store/
│ └── index.ts # Zustand store with state management
├── utils/
│ ├── payment.ts # Payment calculation utilities
│ ├── payment.test.ts # Payment utility tests (use bun test)
│ └── cn.ts # Class name utility
├── main.tsx # App entry point
└── index.css # Styles (tailwindcss)
```
## State Management
The application uses **Zustand** for state management.
A state-machine-like pattern was chosen and **ts-pattern** was used for pattern matching the states.
### Machine States
1. **`idle`**
- Default state when no interaction is happening
- User can select products
- All products are displayed with their prices and stock
2. **`awaiting-payment`**
- Triggered when a user selects an available product
- Tracks the selected product and amount of money inserted
- User can insert cash, pay by card, or cancel the order
- Progresses to `dispensing` state
3. **`dispensing`**
- Product or change is being dispensed
- Tracks whether the user has taken the item and change
- User must collect both item and change (if any) to return to `idle`
4. **`error`**
- Handles various error conditions (invalid product, out of stock, payment failures)
- Stores the previous state to allow recovery
- May include change to be returned to the user
### Store Actions
- `selectProduct(productId)` - Select a product for purchase
- `insertCash(money)` - Insert coins or bills (fail 10% of the time)
- `payByCard()` - Process card payment (async simulation, fail 20% of the time)
- `takeItem()` - Collect only the dispensed item
- `takeChange()` - Collect only the change
- `resetFromError()` - Recover from error state
- `cancelOrder()` - Cancel current order and return inserted money