feat: add POS register screen with full-screen touch-optimized layout

Standalone register at /pos bypassing the admin sidebar layout:
- Two-panel layout: product search/grid (60%) + cart/payment (40%)
- Product search with barcode scan support (UPC lookup on Enter)
- Custom item entry dialog for ad-hoc items
- Cart with line items, tax, totals, and remove-item support
- Payment dialogs: cash (quick amounts + change calc), card, check
- Drawer open/close with balance reconciliation and over/short
- Auto-creates pending transaction on first item added
- POS link added to admin sidebar nav (module-gated)
- Zustand store for POS session state, React Query for server data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ryan
2026-04-04 19:29:37 +00:00
parent bd5f0ca511
commit bd3a25aa1c
11 changed files with 1180 additions and 1 deletions

View File

@@ -9,6 +9,7 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as PosRouteImport } from './routes/pos'
import { Route as LoginRouteImport } from './routes/login'
import { Route as AuthenticatedRouteImport } from './routes/_authenticated'
import { Route as AuthenticatedIndexRouteImport } from './routes/_authenticated/index'
@@ -56,6 +57,11 @@ import { Route as AuthenticatedAccountsAccountIdMembersRouteImport } from './rou
import { Route as AuthenticatedAccountsAccountIdEnrollmentsRouteImport } from './routes/_authenticated/accounts/$accountId/enrollments'
import { Route as AuthenticatedLessonsScheduleInstructorsInstructorIdRouteImport } from './routes/_authenticated/lessons/schedule/instructors/$instructorId'
const PosRoute = PosRouteImport.update({
id: '/pos',
path: '/pos',
getParentRoute: () => rootRouteImport,
} as any)
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
@@ -323,6 +329,7 @@ const AuthenticatedLessonsScheduleInstructorsInstructorIdRoute =
export interface FileRoutesByFullPath {
'/': typeof AuthenticatedIndexRoute
'/login': typeof LoginRoute
'/pos': typeof PosRoute
'/help': typeof AuthenticatedHelpRoute
'/profile': typeof AuthenticatedProfileRoute
'/settings': typeof AuthenticatedSettingsRoute
@@ -369,6 +376,7 @@ export interface FileRoutesByFullPath {
}
export interface FileRoutesByTo {
'/login': typeof LoginRoute
'/pos': typeof PosRoute
'/help': typeof AuthenticatedHelpRoute
'/profile': typeof AuthenticatedProfileRoute
'/settings': typeof AuthenticatedSettingsRoute
@@ -417,6 +425,7 @@ export interface FileRoutesById {
__root__: typeof rootRouteImport
'/_authenticated': typeof AuthenticatedRouteWithChildren
'/login': typeof LoginRoute
'/pos': typeof PosRoute
'/_authenticated/help': typeof AuthenticatedHelpRoute
'/_authenticated/profile': typeof AuthenticatedProfileRoute
'/_authenticated/settings': typeof AuthenticatedSettingsRoute
@@ -467,6 +476,7 @@ export interface FileRouteTypes {
fullPaths:
| '/'
| '/login'
| '/pos'
| '/help'
| '/profile'
| '/settings'
@@ -513,6 +523,7 @@ export interface FileRouteTypes {
fileRoutesByTo: FileRoutesByTo
to:
| '/login'
| '/pos'
| '/help'
| '/profile'
| '/settings'
@@ -560,6 +571,7 @@ export interface FileRouteTypes {
| '__root__'
| '/_authenticated'
| '/login'
| '/pos'
| '/_authenticated/help'
| '/_authenticated/profile'
| '/_authenticated/settings'
@@ -609,10 +621,18 @@ export interface FileRouteTypes {
export interface RootRouteChildren {
AuthenticatedRoute: typeof AuthenticatedRouteWithChildren
LoginRoute: typeof LoginRoute
PosRoute: typeof PosRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/pos': {
id: '/pos'
path: '/pos'
fullPath: '/pos'
preLoaderRoute: typeof PosRouteImport
parentRoute: typeof rootRouteImport
}
'/login': {
id: '/login'
path: '/login'
@@ -1069,6 +1089,7 @@ const AuthenticatedRouteWithChildren = AuthenticatedRoute._addFileChildren(
const rootRouteChildren: RootRouteChildren = {
AuthenticatedRoute: AuthenticatedRouteWithChildren,
LoginRoute: LoginRoute,
PosRoute: PosRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)