pi-kiosk-shared 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Shared API utilities
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.createAPIClient = exports.APIClient = exports.API_ENDPOINTS = void 0;
5
- exports.API_ENDPOINTS = {
2
+ export const API_ENDPOINTS = {
6
3
  PRODUCTS: '/api/products',
7
4
  PRODUCT_CLICK: '/api/products/:id/click',
8
5
  ADMIN_LOGIN: '/admin/login',
@@ -11,7 +8,7 @@ exports.API_ENDPOINTS = {
11
8
  HEALTH: '/health',
12
9
  CHECK_TRANSACTIONS: '/api/check-new-transactions'
13
10
  };
14
- class APIClient {
11
+ export class APIClient {
15
12
  constructor(baseUrl, kioskSecret) {
16
13
  this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
17
14
  this.kioskSecret = kioskSecret;
@@ -54,10 +51,8 @@ class APIClient {
54
51
  return this.request(endpoint, { method: 'DELETE' });
55
52
  }
56
53
  }
57
- exports.APIClient = APIClient;
58
- const environments_1 = require("./config/environments");
59
- const createAPIClient = (baseUrl, kioskSecret) => {
60
- const url = baseUrl || (0, environments_1.getEnvironmentConfig)().apiUrl;
54
+ import { getEnvironmentConfig } from './config/environments';
55
+ export const createAPIClient = (baseUrl, kioskSecret) => {
56
+ const url = baseUrl || getEnvironmentConfig().apiUrl;
61
57
  return new APIClient(url, kioskSecret);
62
58
  };
63
- exports.createAPIClient = createAPIClient;
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ErrorDisplay = ErrorDisplay;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const errors_1 = require("../errors");
6
- const constants_1 = require("../constants");
7
- function ErrorDisplay({ error, onRetry, onDismiss, className = '', showDetails = false, retryLabel = 'Zkusit znovu', dismissLabel = 'Zavřít' }) {
8
- const userMessage = (0, errors_1.getErrorMessage)(error);
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { getErrorMessage } from '../errors';
3
+ import { CSS_CLASSES } from '../constants';
4
+ export function ErrorDisplay({ error, onRetry, onDismiss, className = '', showDetails = false, retryLabel = 'Zkusit znovu', dismissLabel = 'Zavřít' }) {
5
+ const userMessage = getErrorMessage(error);
9
6
  const isNetworkError = error.name === 'NetworkError';
10
- return ((0, jsx_runtime_1.jsx)("div", { className: `error-display ${constants_1.CSS_CLASSES.ERROR} ${className}`, role: "alert", "aria-live": "assertive", children: (0, jsx_runtime_1.jsxs)("div", { className: "error-content", children: [(0, jsx_runtime_1.jsx)("div", { className: "error-icon", "aria-hidden": "true", children: isNetworkError ? '🌐' : '❌' }), (0, jsx_runtime_1.jsxs)("div", { className: "error-text", children: [(0, jsx_runtime_1.jsx)("h3", { className: "error-title", children: isNetworkError ? 'Problém s připojením' : 'Došlo k chybě' }), (0, jsx_runtime_1.jsx)("p", { className: "error-message", children: userMessage })] }), showDetails && process.env.NODE_ENV === 'development' && ((0, jsx_runtime_1.jsxs)("details", { className: "error-details", children: [(0, jsx_runtime_1.jsx)("summary", { children: "Technick\u00E9 detaily" }), (0, jsx_runtime_1.jsx)("pre", { className: "error-stack", children: (0, jsx_runtime_1.jsx)("code", { children: error.stack || error.message }) })] })), (0, jsx_runtime_1.jsxs)("div", { className: "error-actions", children: [onRetry && ((0, jsx_runtime_1.jsxs)("button", { onClick: onRetry, className: `retry-btn ${constants_1.CSS_CLASSES.BUTTON_PRIMARY}`, type: "button", children: ["\uD83D\uDD04 ", retryLabel] })), onDismiss && ((0, jsx_runtime_1.jsxs)("button", { onClick: onDismiss, className: `dismiss-btn ${constants_1.CSS_CLASSES.BUTTON_SECONDARY}`, type: "button", children: ["\u2715 ", dismissLabel] }))] })] }) }));
7
+ return (_jsx("div", { className: `error-display ${CSS_CLASSES.ERROR} ${className}`, role: "alert", "aria-live": "assertive", children: _jsxs("div", { className: "error-content", children: [_jsx("div", { className: "error-icon", "aria-hidden": "true", children: isNetworkError ? '🌐' : '❌' }), _jsxs("div", { className: "error-text", children: [_jsx("h3", { className: "error-title", children: isNetworkError ? 'Problém s připojením' : 'Došlo k chybě' }), _jsx("p", { className: "error-message", children: userMessage })] }), showDetails && process.env.NODE_ENV === 'development' && (_jsxs("details", { className: "error-details", children: [_jsx("summary", { children: "Technick\u00E9 detaily" }), _jsx("pre", { className: "error-stack", children: _jsx("code", { children: error.stack || error.message }) })] })), _jsxs("div", { className: "error-actions", children: [onRetry && (_jsxs("button", { onClick: onRetry, className: `retry-btn ${CSS_CLASSES.BUTTON_PRIMARY}`, type: "button", children: ["\uD83D\uDD04 ", retryLabel] })), onDismiss && (_jsxs("button", { onClick: onDismiss, className: `dismiss-btn ${CSS_CLASSES.BUTTON_SECONDARY}`, type: "button", children: ["\u2715 ", dismissLabel] }))] })] }) }));
11
8
  }
@@ -1,13 +1,10 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LoadingSpinner = LoadingSpinner;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const constants_1 = require("../constants");
6
- function LoadingSpinner({ size = 'medium', message, className = '', 'aria-label': ariaLabel = 'Loading' }) {
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CSS_CLASSES } from '../constants';
3
+ export function LoadingSpinner({ size = 'medium', message, className = '', 'aria-label': ariaLabel = 'Loading' }) {
7
4
  const sizeClass = {
8
5
  small: 'spinner-small',
9
6
  medium: 'spinner-medium',
10
7
  large: 'spinner-large'
11
8
  }[size];
12
- return ((0, jsx_runtime_1.jsxs)("div", { className: `loading-container ${constants_1.CSS_CLASSES.LOADING} ${className}`, children: [(0, jsx_runtime_1.jsx)("div", { className: `spinner ${sizeClass}`, role: "status", "aria-label": ariaLabel, children: (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: ariaLabel }) }), message && ((0, jsx_runtime_1.jsx)("p", { className: "loading-message", "aria-live": "polite", children: message }))] }));
9
+ return (_jsxs("div", { className: `loading-container ${CSS_CLASSES.LOADING} ${className}`, children: [_jsx("div", { className: `spinner ${sizeClass}`, role: "status", "aria-label": ariaLabel, children: _jsx("span", { className: "sr-only", children: ariaLabel }) }), message && (_jsx("p", { className: "loading-message", "aria-live": "polite", children: message }))] }));
13
10
  }
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Deployment configuration for different modes and platforms
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.railwayConfigs = exports.deploymentConfig = void 0;
5
- exports.deploymentConfig = {
2
+ export const deploymentConfig = {
6
3
  railway: {
7
4
  testService: 'kiosk-test',
8
5
  stagingService: 'kiosk-staging',
@@ -49,7 +46,7 @@ exports.deploymentConfig = {
49
46
  }
50
47
  };
51
48
  // Railway deployment configuration files
52
- exports.railwayConfigs = {
49
+ export const railwayConfigs = {
53
50
  test: {
54
51
  build: {
55
52
  builder: 'NIXPACKS'
@@ -64,7 +61,7 @@ exports.railwayConfigs = {
64
61
  name: 'kiosk-backend-test',
65
62
  source: './packages/backend',
66
63
  env: {
67
- ...exports.deploymentConfig.environmentVariables.test,
64
+ ...deploymentConfig.environmentVariables.test,
68
65
  PORT: '3000',
69
66
  FIO_API_MODE: 'test'
70
67
  }
@@ -74,14 +71,14 @@ exports.railwayConfigs = {
74
71
  source: './packages/kiosk-app',
75
72
  buildCommand: 'npm run build',
76
73
  startCommand: 'npx serve -s dist -l 5173',
77
- env: exports.deploymentConfig.environmentVariables.test
74
+ env: deploymentConfig.environmentVariables.test
78
75
  },
79
76
  {
80
77
  name: 'admin-frontend-test',
81
78
  source: './packages/admin-app',
82
79
  buildCommand: 'npm run build',
83
80
  startCommand: 'npx serve -s dist -l 5174',
84
- env: exports.deploymentConfig.environmentVariables.test
81
+ env: deploymentConfig.environmentVariables.test
85
82
  }
86
83
  ]
87
84
  },
@@ -99,7 +96,7 @@ exports.railwayConfigs = {
99
96
  name: 'kiosk-backend-staging',
100
97
  source: './packages/backend',
101
98
  env: {
102
- ...exports.deploymentConfig.environmentVariables.staging,
99
+ ...deploymentConfig.environmentVariables.staging,
103
100
  PORT: '3000'
104
101
  }
105
102
  },
@@ -108,14 +105,14 @@ exports.railwayConfigs = {
108
105
  source: './packages/kiosk-app',
109
106
  buildCommand: 'npm run build',
110
107
  startCommand: 'npx serve -s dist -l 5173',
111
- env: exports.deploymentConfig.environmentVariables.staging
108
+ env: deploymentConfig.environmentVariables.staging
112
109
  },
113
110
  {
114
111
  name: 'admin-frontend-staging',
115
112
  source: './packages/admin-app',
116
113
  buildCommand: 'npm run build',
117
114
  startCommand: 'npx serve -s dist -l 5174',
118
- env: exports.deploymentConfig.environmentVariables.staging
115
+ env: deploymentConfig.environmentVariables.staging
119
116
  }
120
117
  ]
121
118
  },
@@ -133,7 +130,7 @@ exports.railwayConfigs = {
133
130
  name: 'kiosk-backend-prod',
134
131
  source: './packages/backend',
135
132
  env: {
136
- ...exports.deploymentConfig.environmentVariables.production,
133
+ ...deploymentConfig.environmentVariables.production,
137
134
  PORT: '3000'
138
135
  }
139
136
  },
@@ -142,14 +139,14 @@ exports.railwayConfigs = {
142
139
  source: './packages/kiosk-app',
143
140
  buildCommand: 'npm run build',
144
141
  startCommand: 'npx serve -s dist -l 5173',
145
- env: exports.deploymentConfig.environmentVariables.production
142
+ env: deploymentConfig.environmentVariables.production
146
143
  },
147
144
  {
148
145
  name: 'admin-frontend-prod',
149
146
  source: './packages/admin-app',
150
147
  buildCommand: 'npm run build',
151
148
  startCommand: 'npx serve -s dist -l 5174',
152
- env: exports.deploymentConfig.environmentVariables.production
149
+ env: deploymentConfig.environmentVariables.production
153
150
  }
154
151
  ]
155
152
  }
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Centralized environment configuration for all services
3
2
  // This ensures consistency across backend, kiosk, and admin apps
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.getUIConfig = exports.getPaymentConfig = exports.getWsUrl = exports.getApiUrl = exports.getAdminUrl = exports.getKioskUrl = exports.getBackendUrl = exports.isProduction = exports.isDevelopment = exports.getEnvironmentConfig = exports.getCurrentEnvironment = void 0;
6
3
  // Helper function to get environment variables dynamically
7
4
  function getEnvVar(key, defaultValue) {
8
5
  // Try to get from process.env (Node.js) or import.meta.env (Vite)
@@ -14,11 +11,11 @@ function getEnvVar(key, defaultValue) {
14
11
  // If not found and we're in a browser, try to access Vite's environment
15
12
  if (!value && typeof window !== 'undefined') {
16
13
  try {
17
- // Use eval to access import.meta at runtime (not at parse time)
14
+ // Access import.meta.env safely using dynamic import
18
15
  // @ts-ignore
19
- const viteEnv = eval('typeof import !== "undefined" && import.meta && import.meta.env');
20
- if (viteEnv && typeof viteEnv === 'object') {
21
- value = viteEnv[key];
16
+ const meta = globalThis.import?.meta;
17
+ if (meta && meta.env) {
18
+ value = meta.env[key];
22
19
  }
23
20
  }
24
21
  catch (e) {
@@ -85,7 +82,7 @@ function getConfigForEnvironment(env) {
85
82
  }
86
83
  }
87
84
  // Simple environment detection
88
- const getCurrentEnvironment = () => {
85
+ export const getCurrentEnvironment = () => {
89
86
  let nodeEnv;
90
87
  // Check for process.env (Node.js environment)
91
88
  if (typeof process !== 'undefined' && process.env) {
@@ -94,11 +91,11 @@ const getCurrentEnvironment = () => {
94
91
  // If not found and we're in a browser, try to access Vite's environment
95
92
  if (!nodeEnv && typeof window !== 'undefined') {
96
93
  try {
97
- // Use eval to access import.meta at runtime (not at parse time)
94
+ // Access import.meta.env safely using dynamic import
98
95
  // @ts-ignore
99
- const viteEnv = eval('typeof import !== "undefined" && import.meta && import.meta.env');
100
- if (viteEnv && typeof viteEnv === 'object') {
101
- nodeEnv = viteEnv.NODE_ENV;
96
+ const meta = globalThis.import?.meta;
97
+ if (meta && meta.env) {
98
+ nodeEnv = meta.env.NODE_ENV;
102
99
  }
103
100
  }
104
101
  catch (e) {
@@ -114,44 +111,33 @@ const getCurrentEnvironment = () => {
114
111
  }
115
112
  return nodeEnv === 'production' ? 'production' : 'development';
116
113
  };
117
- exports.getCurrentEnvironment = getCurrentEnvironment;
118
114
  // Get current environment configuration
119
- const getEnvironmentConfig = () => {
120
- const env = (0, exports.getCurrentEnvironment)();
115
+ export const getEnvironmentConfig = () => {
116
+ const env = getCurrentEnvironment();
121
117
  return getConfigForEnvironment(env);
122
118
  };
123
- exports.getEnvironmentConfig = getEnvironmentConfig;
124
119
  // Simple environment checks
125
- const isDevelopment = () => (0, exports.getCurrentEnvironment)() === 'development';
126
- exports.isDevelopment = isDevelopment;
127
- const isProduction = () => (0, exports.getCurrentEnvironment)() === 'production';
128
- exports.isProduction = isProduction;
120
+ export const isDevelopment = () => getCurrentEnvironment() === 'development';
121
+ export const isProduction = () => getCurrentEnvironment() === 'production';
129
122
  // Utility functions for easy access to service URLs
130
- const getBackendUrl = () => (0, exports.getEnvironmentConfig)().backendUrl;
131
- exports.getBackendUrl = getBackendUrl;
132
- const getKioskUrl = () => (0, exports.getEnvironmentConfig)().kioskUrl;
133
- exports.getKioskUrl = getKioskUrl;
134
- const getAdminUrl = () => (0, exports.getEnvironmentConfig)().adminUrl;
135
- exports.getAdminUrl = getAdminUrl;
136
- const getApiUrl = () => (0, exports.getEnvironmentConfig)().apiUrl;
137
- exports.getApiUrl = getApiUrl;
138
- const getWsUrl = () => (0, exports.getEnvironmentConfig)().wsUrl;
139
- exports.getWsUrl = getWsUrl;
123
+ export const getBackendUrl = () => getEnvironmentConfig().backendUrl;
124
+ export const getKioskUrl = () => getEnvironmentConfig().kioskUrl;
125
+ export const getAdminUrl = () => getEnvironmentConfig().adminUrl;
126
+ export const getApiUrl = () => getEnvironmentConfig().apiUrl;
127
+ export const getWsUrl = () => getEnvironmentConfig().wsUrl;
140
128
  // Service-specific configuration helpers
141
- const getPaymentConfig = () => {
142
- const config = (0, exports.getEnvironmentConfig)();
129
+ export const getPaymentConfig = () => {
130
+ const config = getEnvironmentConfig();
143
131
  return {
144
132
  enableMockPayments: config.enableMockPayments,
145
133
  paymentAccountNumber: config.paymentAccountNumber,
146
134
  paymentMode: config.paymentMode,
147
135
  };
148
136
  };
149
- exports.getPaymentConfig = getPaymentConfig;
150
- const getUIConfig = () => {
151
- const config = (0, exports.getEnvironmentConfig)();
137
+ export const getUIConfig = () => {
138
+ const config = getEnvironmentConfig();
152
139
  return {
153
140
  showDebugInfo: config.showDebugInfo,
154
141
  logLevel: config.logLevel,
155
142
  };
156
143
  };
157
- exports.getUIConfig = getUIConfig;
@@ -1,11 +1,8 @@
1
- "use strict";
2
1
  // Centralized logging system with environment-aware configuration
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.log = exports.logger = void 0;
5
- const environments_1 = require("./environments");
2
+ import { getEnvironmentConfig, getCurrentEnvironment } from './environments';
6
3
  class Logger {
7
4
  constructor() {
8
- this.config = (0, environments_1.getEnvironmentConfig)();
5
+ this.config = getEnvironmentConfig();
9
6
  this.sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
10
7
  }
11
8
  shouldLog(level) {
@@ -26,7 +23,7 @@ class Logger {
26
23
  context,
27
24
  data,
28
25
  timestamp: new Date().toISOString(),
29
- environment: (0, environments_1.getCurrentEnvironment)(),
26
+ environment: getCurrentEnvironment(),
30
27
  sessionId: this.sessionId
31
28
  };
32
29
  }
@@ -107,14 +104,14 @@ class Logger {
107
104
  }
108
105
  }
109
106
  // Export singleton instance
110
- exports.logger = new Logger();
107
+ export const logger = new Logger();
111
108
  // Export convenience functions
112
- exports.log = {
113
- debug: (message, context, data) => exports.logger.debug(message, context, data),
114
- info: (message, context, data) => exports.logger.info(message, context, data),
115
- warn: (message, context, data) => exports.logger.warn(message, context, data),
116
- error: (message, context, data) => exports.logger.error(message, context, data),
117
- kioskAction: (action, kioskId, data) => exports.logger.kioskAction(action, kioskId, data),
118
- paymentEvent: (event, paymentId, data) => exports.logger.paymentEvent(event, paymentId, data),
119
- apiCall: (method, endpoint, duration, error) => exports.logger.apiCall(method, endpoint, duration, error),
109
+ export const log = {
110
+ debug: (message, context, data) => logger.debug(message, context, data),
111
+ info: (message, context, data) => logger.info(message, context, data),
112
+ warn: (message, context, data) => logger.warn(message, context, data),
113
+ error: (message, context, data) => logger.error(message, context, data),
114
+ kioskAction: (action, kioskId, data) => logger.kioskAction(action, kioskId, data),
115
+ paymentEvent: (event, paymentId, data) => logger.paymentEvent(event, paymentId, data),
116
+ apiCall: (method, endpoint, duration, error) => logger.apiCall(method, endpoint, duration, error),
120
117
  };
@@ -36,11 +36,19 @@ export declare const UI_MESSAGES: {
36
36
  readonly REQUIRED_FIELD: "Toto pole je povinné";
37
37
  readonly INVALID_EMAIL: "Zadejte platnou emailovou adresu";
38
38
  readonly INVALID_PRICE: "Cena musí být větší než 0";
39
+ readonly EMAIL_LABEL: "Váš email:";
40
+ readonly SELECT_PRODUCT: "Vyberte si produkt";
41
+ readonly PAYMENT_WAITING: "Čekám na platbu...";
42
+ readonly PAYMENT_CONFIRMED: "Platba potvrzena!";
43
+ readonly CONTINUE_SHOPPING: "Pokračovat v nákupu";
44
+ readonly BACK_TO_PRODUCTS: "Zpět na produkty";
39
45
  };
40
46
  export declare const CSS_CLASSES: {
41
47
  readonly CONTAINER: "container";
42
48
  readonly GRID: "grid";
43
49
  readonly FLEX: "flex";
50
+ readonly APP: "kiosk-app";
51
+ readonly SCREEN: "screen";
44
52
  readonly LOADING: "loading";
45
53
  readonly ERROR: "error";
46
54
  readonly SUCCESS: "success";
package/dist/constants.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Shared constants across all packages
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.ROUTES = exports.CSS_CLASSES = exports.UI_MESSAGES = exports.APP_CONFIG = void 0;
5
- exports.APP_CONFIG = {
2
+ export const APP_CONFIG = {
6
3
  // API Configuration
7
4
  DEFAULT_API_URL: 'http://localhost:3015',
8
5
  DEFAULT_WS_URL: 'ws://localhost:3015',
@@ -32,7 +29,7 @@ exports.APP_CONFIG = {
32
29
  QR_CODE_WIDTH: 300,
33
30
  QR_CODE_FORMAT: 'SPD*1.0', // Czech QR payment standard
34
31
  };
35
- exports.UI_MESSAGES = {
32
+ export const UI_MESSAGES = {
36
33
  // Loading states
37
34
  LOADING_PRODUCTS: 'Načítání produktů...',
38
35
  LOADING_PAYMENT: 'Zpracovávám platbu...',
@@ -52,12 +49,21 @@ exports.UI_MESSAGES = {
52
49
  REQUIRED_FIELD: 'Toto pole je povinné',
53
50
  INVALID_EMAIL: 'Zadejte platnou emailovou adresu',
54
51
  INVALID_PRICE: 'Cena musí být větší než 0',
52
+ EMAIL_LABEL: 'Váš email:',
53
+ // Kiosk specific
54
+ SELECT_PRODUCT: 'Vyberte si produkt',
55
+ PAYMENT_WAITING: 'Čekám na platbu...',
56
+ PAYMENT_CONFIRMED: 'Platba potvrzena!',
57
+ CONTINUE_SHOPPING: 'Pokračovat v nákupu',
58
+ BACK_TO_PRODUCTS: 'Zpět na produkty',
55
59
  };
56
- exports.CSS_CLASSES = {
60
+ export const CSS_CLASSES = {
57
61
  // Layout
58
62
  CONTAINER: 'container',
59
63
  GRID: 'grid',
60
64
  FLEX: 'flex',
65
+ APP: 'kiosk-app',
66
+ SCREEN: 'screen',
61
67
  // States
62
68
  LOADING: 'loading',
63
69
  ERROR: 'error',
@@ -75,7 +81,7 @@ exports.CSS_CLASSES = {
75
81
  CONNECTED: 'connected',
76
82
  DISCONNECTED: 'disconnected',
77
83
  };
78
- exports.ROUTES = {
84
+ export const ROUTES = {
79
85
  // Kiosk routes
80
86
  KIOSK_HOME: '/',
81
87
  KIOSK_PAYMENT: '/payment',
package/dist/errors.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Shared error handling system
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getErrorMessage = exports.formatError = exports.NotFoundError = exports.AuthenticationError = exports.NetworkError = exports.ValidationError = exports.AppError = void 0;
5
- class AppError extends Error {
2
+ export class AppError extends Error {
6
3
  constructor(message, code = 'UNKNOWN_ERROR', statusCode = 500, isOperational = true) {
7
4
  super(message);
8
5
  this.name = 'AppError';
@@ -13,37 +10,32 @@ class AppError extends Error {
13
10
  Error.captureStackTrace(this, this.constructor);
14
11
  }
15
12
  }
16
- exports.AppError = AppError;
17
13
  // Predefined error types
18
- class ValidationError extends AppError {
14
+ export class ValidationError extends AppError {
19
15
  constructor(message, _field) {
20
16
  super(message, 'VALIDATION_ERROR', 400);
21
17
  this.name = 'ValidationError';
22
18
  }
23
19
  }
24
- exports.ValidationError = ValidationError;
25
- class NetworkError extends AppError {
20
+ export class NetworkError extends AppError {
26
21
  constructor(message = 'Chyba připojení k serveru') {
27
22
  super(message, 'NETWORK_ERROR', 503);
28
23
  this.name = 'NetworkError';
29
24
  }
30
25
  }
31
- exports.NetworkError = NetworkError;
32
- class AuthenticationError extends AppError {
26
+ export class AuthenticationError extends AppError {
33
27
  constructor(message = 'Neplatné přihlašovací údaje') {
34
28
  super(message, 'AUTH_ERROR', 401);
35
29
  this.name = 'AuthenticationError';
36
30
  }
37
31
  }
38
- exports.AuthenticationError = AuthenticationError;
39
- class NotFoundError extends AppError {
32
+ export class NotFoundError extends AppError {
40
33
  constructor(resource = 'Zdroj') {
41
34
  super(`${resource} nebyl nalezen`, 'NOT_FOUND', 404);
42
35
  this.name = 'NotFoundError';
43
36
  }
44
37
  }
45
- exports.NotFoundError = NotFoundError;
46
- const formatError = (error, details) => {
38
+ export const formatError = (error, details) => {
47
39
  const isAppError = error instanceof AppError;
48
40
  return {
49
41
  success: false,
@@ -55,9 +47,8 @@ const formatError = (error, details) => {
55
47
  }
56
48
  };
57
49
  };
58
- exports.formatError = formatError;
59
50
  // Error handler hook for React components
60
- const getErrorMessage = (error) => {
51
+ export const getErrorMessage = (error) => {
61
52
  if (error instanceof NetworkError) {
62
53
  return 'Problém s připojením. Zkuste to znovu.';
63
54
  }
@@ -80,4 +71,3 @@ const getErrorMessage = (error) => {
80
71
  // Return original message if available, otherwise generic
81
72
  return error.message || 'Něco se pokazilo. Zkuste to znovu.';
82
73
  };
83
- exports.getErrorMessage = getErrorMessage;
@@ -1,15 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useApi = useApi;
4
- const react_1 = require("react");
5
- const errors_1 = require("../errors");
6
- function useApi(_apiClient) {
7
- const [state, setState] = (0, react_1.useState)({
1
+ import { useState, useCallback } from 'react';
2
+ import { NetworkError, AppError } from '../errors';
3
+ export function useApi(_apiClient) {
4
+ const [state, setState] = useState({
8
5
  data: null,
9
6
  loading: false,
10
7
  error: null
11
8
  });
12
- const execute = (0, react_1.useCallback)(async (apiCall, options) => {
9
+ const execute = useCallback(async (apiCall, options) => {
13
10
  try {
14
11
  if (!options?.skipLoading) {
15
12
  setState(prev => ({ ...prev, loading: true, error: null }));
@@ -24,9 +21,9 @@ function useApi(_apiClient) {
24
21
  return data;
25
22
  }
26
23
  catch (error) {
27
- const appError = error instanceof errors_1.AppError
24
+ const appError = error instanceof AppError
28
25
  ? error
29
- : new errors_1.NetworkError('Chyba při komunikaci se serverem');
26
+ : new NetworkError('Chyba při komunikaci se serverem');
30
27
  setState(prev => ({
31
28
  ...prev,
32
29
  loading: false,
@@ -36,7 +33,7 @@ function useApi(_apiClient) {
36
33
  throw appError;
37
34
  }
38
35
  }, []);
39
- const reset = (0, react_1.useCallback)(() => {
36
+ const reset = useCallback(() => {
40
37
  setState({
41
38
  data: null,
42
39
  loading: false,
@@ -1,19 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useAsyncOperation = useAsyncOperation;
4
- const react_1 = require("react");
5
- const useErrorHandler_1 = require("./useErrorHandler");
1
+ import { useState, useCallback } from 'react';
2
+ import { useErrorHandler } from './useErrorHandler';
6
3
  /**
7
4
  * Consistent hook for handling async operations with loading states and error handling
8
5
  */
9
- function useAsyncOperation(options = {}) {
10
- const [state, setState] = (0, react_1.useState)({
6
+ export function useAsyncOperation(options = {}) {
7
+ const [state, setState] = useState({
11
8
  data: options.initialData || null,
12
9
  loading: false,
13
10
  error: null
14
11
  });
15
- const { handleError } = (0, useErrorHandler_1.useErrorHandler)();
16
- const execute = (0, react_1.useCallback)(async (operation, context) => {
12
+ const { handleError } = useErrorHandler();
13
+ const execute = useCallback(async (operation, context) => {
17
14
  setState(prev => ({ ...prev, loading: true, error: null }));
18
15
  try {
19
16
  const result = await operation();
@@ -37,14 +34,14 @@ function useAsyncOperation(options = {}) {
37
34
  return null;
38
35
  }
39
36
  }, [handleError, options]);
40
- const reset = (0, react_1.useCallback)(() => {
37
+ const reset = useCallback(() => {
41
38
  setState({
42
39
  data: options.initialData || null,
43
40
  loading: false,
44
41
  error: null
45
42
  });
46
43
  }, [options.initialData]);
47
- const setData = (0, react_1.useCallback)((data) => {
44
+ const setData = useCallback((data) => {
48
45
  setState(prev => ({ ...prev, data }));
49
46
  }, []);
50
47
  return {
@@ -1,17 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useErrorHandler = useErrorHandler;
4
- const react_1 = require("react");
5
- const errors_1 = require("../errors");
6
- function useErrorHandler() {
7
- const [errorState, setErrorState] = (0, react_1.useState)({
1
+ import { useCallback, useState } from 'react';
2
+ import { getErrorMessage, formatError } from '../errors';
3
+ export function useErrorHandler() {
4
+ const [errorState, setErrorState] = useState({
8
5
  error: null,
9
6
  message: '',
10
7
  isVisible: false
11
8
  });
12
- const handleError = (0, react_1.useCallback)((error, context) => {
9
+ const handleError = useCallback((error, context) => {
13
10
  console.error(`Error in ${context || 'unknown context'}:`, error);
14
- const userMessage = (0, errors_1.getErrorMessage)(error);
11
+ const userMessage = getErrorMessage(error);
15
12
  setErrorState({
16
13
  error,
17
14
  message: userMessage,
@@ -24,17 +21,17 @@ function useErrorHandler() {
24
21
  // Send to monitoring service in production
25
22
  if (process.env.NODE_ENV === 'production') {
26
23
  // TODO: Integrate with monitoring service (Sentry, LogRocket, etc.)
27
- console.warn('Production error logged:', (0, errors_1.formatError)(error));
24
+ console.warn('Production error logged:', formatError(error));
28
25
  }
29
26
  }, []);
30
- const clearError = (0, react_1.useCallback)(() => {
27
+ const clearError = useCallback(() => {
31
28
  setErrorState({
32
29
  error: null,
33
30
  message: '',
34
31
  isVisible: false
35
32
  });
36
33
  }, []);
37
- const retryAction = (0, react_1.useCallback)((action) => {
34
+ const retryAction = useCallback((action) => {
38
35
  clearError();
39
36
  try {
40
37
  const result = action();
package/dist/index.js CHANGED
@@ -1,31 +1,15 @@
1
- "use strict";
2
1
  // Shared package entry point
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
- };
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- __exportStar(require("./types"), exports);
19
- __exportStar(require("./api"), exports);
20
- __exportStar(require("./constants"), exports);
21
- __exportStar(require("./validation"), exports);
22
- __exportStar(require("./errors"), exports);
23
- __exportStar(require("./utils"), exports);
2
+ export * from './types';
3
+ export * from './api';
4
+ export * from './constants';
5
+ export * from './validation';
6
+ export * from './errors';
7
+ export * from './utils';
24
8
  // Note: ./utils exports getErrorMessage which shadows the one from ./errors
25
- __exportStar(require("./hooks/useErrorHandler"), exports);
26
- __exportStar(require("./hooks/useApi"), exports);
27
- __exportStar(require("./hooks/useAsyncOperation"), exports);
28
- __exportStar(require("./components/LoadingSpinner"), exports);
29
- __exportStar(require("./components/ErrorDisplay"), exports);
30
- __exportStar(require("./config/environments"), exports);
31
- __exportStar(require("./config/logger"), exports);
9
+ export * from './hooks/useErrorHandler';
10
+ export * from './hooks/useApi';
11
+ export * from './hooks/useAsyncOperation';
12
+ export * from './components/LoadingSpinner';
13
+ export * from './components/ErrorDisplay';
14
+ export * from './config/environments';
15
+ export * from './config/logger';
package/dist/types.js CHANGED
@@ -1,3 +1,2 @@
1
- "use strict";
2
1
  // Shared types across all packages
3
- Object.defineProperty(exports, "__esModule", { value: true });
2
+ export {};
package/dist/utils.d.ts CHANGED
@@ -5,3 +5,4 @@ export declare const getKioskSecretFromUrl: () => string | undefined;
5
5
  export declare const formatDate: (date: Date | string) => string;
6
6
  export declare const debounce: <T extends (...args: any[]) => any>(func: T, delay: number) => ((...args: Parameters<T>) => void);
7
7
  export declare const generatePaymentId: () => string;
8
+ export declare const validateKioskId: (kioskId: number) => boolean;
package/dist/utils.js CHANGED
@@ -1,30 +1,31 @@
1
- "use strict";
2
1
  // Shared utility functions - consolidated from utils/simple.ts
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.generatePaymentId = exports.debounce = exports.formatDate = exports.getKioskSecretFromUrl = exports.getKioskIdFromUrl = exports.formatPrice = exports.validateEmail = void 0;
5
- const validateEmail = (email) => {
2
+ export const validateEmail = (email) => {
6
3
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7
4
  // Additional check for consecutive dots which are invalid
8
5
  if (email.includes('..'))
9
6
  return false;
10
7
  return emailRegex.test(email);
11
8
  };
12
- exports.validateEmail = validateEmail;
13
- const formatPrice = (price) => {
9
+ export const formatPrice = (price) => {
14
10
  return `${price} Kč`;
15
11
  };
16
- exports.formatPrice = formatPrice;
17
- const getKioskIdFromUrl = () => {
12
+ export const getKioskIdFromUrl = () => {
18
13
  const urlParams = new URLSearchParams(window.location.search);
19
- return parseInt(urlParams.get('kioskId') || '1');
14
+ const kioskId = urlParams.get('kioskId');
15
+ if (!kioskId) {
16
+ throw new Error('Kiosk ID is required. Please add ?kioskId=X to the URL where X is your kiosk number.');
17
+ }
18
+ const parsedId = parseInt(kioskId);
19
+ if (isNaN(parsedId) || parsedId <= 0) {
20
+ throw new Error(`Invalid kiosk ID: ${kioskId}. Kiosk ID must be a positive number.`);
21
+ }
22
+ return parsedId;
20
23
  };
21
- exports.getKioskIdFromUrl = getKioskIdFromUrl;
22
- const getKioskSecretFromUrl = () => {
24
+ export const getKioskSecretFromUrl = () => {
23
25
  const urlParams = new URLSearchParams(window.location.search);
24
26
  return urlParams.get('secret') || undefined;
25
27
  };
26
- exports.getKioskSecretFromUrl = getKioskSecretFromUrl;
27
- const formatDate = (date) => {
28
+ export const formatDate = (date) => {
28
29
  const d = typeof date === 'string' ? new Date(date) : date;
29
30
  return d.toLocaleDateString('cs-CZ', {
30
31
  year: 'numeric',
@@ -34,17 +35,17 @@ const formatDate = (date) => {
34
35
  minute: '2-digit'
35
36
  });
36
37
  };
37
- exports.formatDate = formatDate;
38
- const debounce = (func, delay) => {
38
+ export const debounce = (func, delay) => {
39
39
  let timeoutId;
40
40
  return (...args) => {
41
41
  clearTimeout(timeoutId);
42
42
  timeoutId = setTimeout(() => func(...args), delay);
43
43
  };
44
44
  };
45
- exports.debounce = debounce;
46
- const generatePaymentId = () => {
45
+ export const generatePaymentId = () => {
47
46
  return `pay-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
48
47
  };
49
- exports.generatePaymentId = generatePaymentId;
48
+ export const validateKioskId = (kioskId) => {
49
+ return Number.isInteger(kioskId) && kioskId > 0;
50
+ };
50
51
  // Note: getErrorMessage is now exported from ./errors.ts instead
@@ -1,13 +1,10 @@
1
- "use strict";
2
1
  // Shared validation utilities
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.validationSchemas = exports.validateSchema = exports.validators = void 0;
5
2
  // ValidationError is imported but not used directly in this file
6
- const constants_1 = require("./constants");
7
- exports.validators = {
3
+ import { APP_CONFIG, UI_MESSAGES } from './constants';
4
+ export const validators = {
8
5
  required: (value) => {
9
6
  if (value === null || value === undefined || value === '') {
10
- return constants_1.UI_MESSAGES.REQUIRED_FIELD;
7
+ return UI_MESSAGES.REQUIRED_FIELD;
11
8
  }
12
9
  return null;
13
10
  },
@@ -16,7 +13,7 @@ exports.validators = {
16
13
  return null; // Let required validator handle empty values
17
14
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
18
15
  if (!emailRegex.test(value)) {
19
- return constants_1.UI_MESSAGES.INVALID_EMAIL;
16
+ return UI_MESSAGES.INVALID_EMAIL;
20
17
  }
21
18
  return null;
22
19
  },
@@ -47,8 +44,8 @@ exports.validators = {
47
44
  username: (value) => {
48
45
  if (!value)
49
46
  return null;
50
- if (value.length < constants_1.APP_CONFIG.MIN_USERNAME_LENGTH) {
51
- return `Uživatelské jméno musí mít alespoň ${constants_1.APP_CONFIG.MIN_USERNAME_LENGTH} znaky`;
47
+ if (value.length < APP_CONFIG.MIN_USERNAME_LENGTH) {
48
+ return `Uživatelské jméno musí mít alespoň ${APP_CONFIG.MIN_USERNAME_LENGTH} znaky`;
52
49
  }
53
50
  if (!/^[a-zA-Z0-9_]+$/.test(value)) {
54
51
  return 'Uživatelské jméno může obsahovat pouze písmena, číslice a podtržítka';
@@ -58,13 +55,13 @@ exports.validators = {
58
55
  password: (value) => {
59
56
  if (!value)
60
57
  return null;
61
- if (value.length < constants_1.APP_CONFIG.MIN_PASSWORD_LENGTH) {
62
- return `Heslo musí mít alespoň ${constants_1.APP_CONFIG.MIN_PASSWORD_LENGTH} znaků`;
58
+ if (value.length < APP_CONFIG.MIN_PASSWORD_LENGTH) {
59
+ return `Heslo musí mít alespoň ${APP_CONFIG.MIN_PASSWORD_LENGTH} znaků`;
63
60
  }
64
61
  return null;
65
62
  }
66
63
  };
67
- const validateSchema = (data, schema) => {
64
+ export const validateSchema = (data, schema) => {
68
65
  const errors = {};
69
66
  for (const [field, validatorFunctions] of Object.entries(schema)) {
70
67
  const value = data[field];
@@ -81,37 +78,36 @@ const validateSchema = (data, schema) => {
81
78
  errors
82
79
  };
83
80
  };
84
- exports.validateSchema = validateSchema;
85
81
  // Common validation schemas
86
- exports.validationSchemas = {
82
+ export const validationSchemas = {
87
83
  login: {
88
84
  username: [
89
- (value) => exports.validators.required(value),
90
- exports.validators.username
85
+ (value) => validators.required(value),
86
+ validators.username
91
87
  ],
92
88
  password: [
93
- (value) => exports.validators.required(value),
94
- exports.validators.password
89
+ (value) => validators.required(value),
90
+ validators.password
95
91
  ]
96
92
  },
97
93
  customerEmail: {
98
94
  email: [
99
- (value) => exports.validators.required(value),
100
- exports.validators.email
95
+ (value) => validators.required(value),
96
+ validators.email
101
97
  ]
102
98
  },
103
99
  product: {
104
100
  name: [
105
- (value) => exports.validators.required(value),
106
- (value) => exports.validators.minLength(value, 2, 'Název produktu'),
107
- (value) => exports.validators.maxLength(value, constants_1.APP_CONFIG.MAX_PRODUCT_NAME_LENGTH, 'Název produktu')
101
+ (value) => validators.required(value),
102
+ (value) => validators.minLength(value, 2, 'Název produktu'),
103
+ (value) => validators.maxLength(value, APP_CONFIG.MAX_PRODUCT_NAME_LENGTH, 'Název produktu')
108
104
  ],
109
105
  price: [
110
- (value) => exports.validators.required(value),
111
- (value) => exports.validators.positiveNumber(value, 'Cena')
106
+ (value) => validators.required(value),
107
+ (value) => validators.positiveNumber(value, 'Cena')
112
108
  ],
113
109
  description: [
114
- (value) => exports.validators.maxLength(value, constants_1.APP_CONFIG.MAX_DESCRIPTION_LENGTH, 'Popis')
110
+ (value) => validators.maxLength(value, APP_CONFIG.MAX_DESCRIPTION_LENGTH, 'Popis')
115
111
  ]
116
112
  }
117
113
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-kiosk-shared",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "private": false,
5
5
  "description": "Shared components and utilities for Pi Kiosk system",
6
6
  "keywords": [
@@ -31,6 +31,8 @@
31
31
  "test": "jest",
32
32
  "test:watch": "jest --watch",
33
33
  "test:coverage": "jest --coverage",
34
+ "clean": "rimraf dist",
35
+ "publish:local": "npm run build && npm pack --pack-destination ../",
34
36
  "prepublishOnly": "npm run build",
35
37
  "preversion": "npm run test",
36
38
  "postversion": "git push && git push --tags"
@@ -48,6 +50,7 @@
48
50
  "@types/node": "^20.0.0",
49
51
  "@types/react": "^18.2.0",
50
52
  "jest": "^29.5.0",
51
- "ts-jest": "^29.1.0"
53
+ "ts-jest": "^29.1.0",
54
+ "rimraf": "^5.0.0"
52
55
  }
53
56
  }