├── public ├── error.log ├── favicon.ico ├── logo192.png ├── logo512.png ├── robots.txt └── manifest.json ├── src ├── lib │ ├── .gitignore │ ├── uuid │ │ └── v4.ts │ ├── http │ │ ├── mime │ │ │ └── mime.ts │ │ ├── exception │ │ │ ├── error.exception.ts │ │ │ ├── http.exception.factory.ts │ │ │ └── http.exception.ts │ │ ├── header │ │ │ ├── header.ts │ │ │ └── compose.ts │ │ └── request.ts │ ├── localforage │ │ └── localforage.ts │ ├── validator │ │ └── validation.result.ts │ ├── error │ │ └── error.tsx │ ├── location │ │ └── query.string.ts │ └── currency │ │ └── currency.ts ├── language │ └── lang.en.json ├── api │ ├── exception │ │ ├── index.ts │ │ └── validation │ │ │ ├── validation.exception.factory.ts │ │ │ └── validation.exception.ts │ ├── graphql │ │ └── terminals.ts │ ├── config │ │ ├── route.config.ts │ │ └── fetch.config.ts │ ├── model │ │ ├── common.ts │ │ ├── coupn.ts │ │ ├── device.ts │ │ ├── brand.ts │ │ ├── order.tax.ts │ │ ├── media.ts │ │ ├── tax.ts │ │ ├── order.discount.ts │ │ ├── category.ts │ │ ├── expense.ts │ │ ├── order.payment.ts │ │ ├── store.ts │ │ ├── payment.type.ts │ │ ├── user.ts │ │ ├── customer.payment.ts │ │ ├── supplier.payment.ts │ │ ├── department.ts │ │ ├── product.store.ts │ │ ├── setting.ts │ │ ├── barcode.ts │ │ ├── product.variant.ts │ │ ├── product.price.ts │ │ ├── purchase.order.ts │ │ ├── terminal.ts │ │ ├── discount.ts │ │ ├── cart.item.ts │ │ ├── customer.ts │ │ ├── closing.ts │ │ ├── purchase.order.item.ts │ │ ├── supplier.ts │ │ ├── purchase.ts │ │ ├── hydra.ts │ │ ├── purchase.item.ts │ │ ├── validation │ │ │ └── index.ts │ │ ├── order.item.ts │ │ ├── order.ts │ │ └── product.ts │ ├── routing │ │ ├── url.ts │ │ └── routes │ │ │ └── admin.backend.app.ts │ ├── request │ │ ├── header.ts │ │ └── request.ts │ ├── api │ │ └── account │ │ │ └── info.ts │ └── hooks │ │ ├── use.load.item.ts │ │ └── use.api.ts ├── __generated__ │ ├── index.ts │ └── fragment-masking.ts ├── assets │ ├── images │ │ ├── login.jpg │ │ ├── 1120171.jpg │ │ ├── download.png │ │ ├── ec3mqt9a91j81.jpg │ │ ├── minus.svg │ │ ├── delete.svg │ │ ├── close.svg │ │ ├── plus.svg │ │ ├── spinner.svg │ │ ├── bars-solid.svg │ │ └── tachometer-alt-solid.svg │ └── fonts │ │ ├── digital-7.ttf │ │ ├── Manrope-Medium.ttf │ │ ├── Comfortaa-Regular.ttf │ │ └── MonaspaceRadon-Medium.woff ├── css │ └── index.scss ├── duck │ ├── entity │ │ ├── entity.model.ts │ │ ├── entity.state.ts │ │ ├── entity.schema.ts │ │ ├── selector │ │ │ ├── user.account.ts │ │ │ └── _entity.ts │ │ ├── entity.action.ts │ │ ├── entity.middleware.ts │ │ └── entity.reducer.ts │ ├── touch │ │ ├── touch.state.ts │ │ ├── touch.action.ts │ │ ├── touch.selector.ts │ │ └── touch.reducer.ts │ ├── progress │ │ ├── progress.state.ts │ │ ├── progress.action.ts │ │ ├── progress.selector.ts │ │ └── progress.reducer.ts │ ├── store │ │ ├── store.action.ts │ │ ├── store.state.ts │ │ ├── store.selector.ts │ │ └── store.reducer.ts │ ├── app │ │ ├── app.state.ts │ │ ├── app.action.ts │ │ ├── app.selector.ts │ │ ├── app.reducer.ts │ │ └── app.saga.ts │ ├── auth │ │ ├── auth.state.ts │ │ ├── model │ │ │ └── authorized.user.ts │ │ ├── auth.reducer.ts │ │ ├── auth.action.ts │ │ ├── auth.selector.ts │ │ ├── hooks │ │ │ └── useLogout.ts │ │ └── auth.saga.ts │ ├── terminal │ │ ├── terminal.action.ts │ │ ├── terminal.state.ts │ │ ├── terminal.selector.ts │ │ └── terminal.reducer.ts │ ├── _root │ │ ├── root.saga.ts │ │ ├── root.state.ts │ │ └── root.reducer.ts │ └── shortcuts │ │ ├── shortcut.action.ts │ │ ├── shortcut.state.ts │ │ ├── shortcut.selector.ts │ │ └── shortcut.reducer.ts ├── ga.js ├── setupTests.js ├── reportWebVitals.js ├── react-app-env.d.ts ├── app-frontend │ ├── routes │ │ └── frontend.routes.ts │ ├── components │ │ ├── print.tsx │ │ ├── logout.tsx │ │ ├── modes │ │ │ ├── footer.tsx │ │ │ └── topbar.right.tsx │ │ ├── settings │ │ │ ├── items │ │ │ │ ├── export.items.tsx │ │ │ │ ├── import.items.tsx │ │ │ │ └── products │ │ │ │ │ ├── variant.group.tsx │ │ │ │ │ └── variants.tsx │ │ │ ├── dynamic-barcodes │ │ │ │ └── index.tsx │ │ │ └── stores │ │ │ │ └── stores.tsx │ │ ├── confirm.box.tsx │ │ ├── search │ │ │ ├── speech.search.tsx │ │ │ ├── sale.brands.tsx │ │ │ ├── sale.categories.tsx │ │ │ ├── sale.departments.tsx │ │ │ └── search.variants.tsx │ │ ├── sale │ │ │ ├── sale.tsx │ │ │ ├── clear.sale.tsx │ │ │ ├── apply.tax.tsx │ │ │ └── sale.find.tsx │ │ ├── inventory │ │ │ └── purchase.tabs.tsx │ │ └── shortcuts.tsx │ ├── containers │ │ └── layout │ │ │ ├── layout.tsx │ │ │ └── dashboard.layout.tsx │ └── app.tsx ├── app-common │ └── components │ │ ├── ga │ │ └── ga4.tsx │ │ ├── input │ │ ├── textarea.tsx │ │ ├── switch.tsx │ │ ├── checkbox.intermediate.tsx │ │ ├── keyboard.input.tsx │ │ ├── button.tsx │ │ ├── checkbox.tsx │ │ ├── stores.tsx │ │ ├── input.tsx │ │ ├── shortcut.tsx │ │ └── custom.react.select.tsx │ │ ├── confirm │ │ ├── notification.ts │ │ └── confirm.alert.tsx │ │ ├── error │ │ └── 404.tsx │ │ ├── loader │ │ └── loader.tsx │ │ ├── dynamic.value │ │ └── dynamic.value.tsx │ │ ├── container │ │ └── trap.focus.tsx │ │ ├── react-aria │ │ └── dropdown.menu.tsx │ │ ├── modal │ │ └── modal.tsx │ │ └── tabs │ │ └── tabs.tsx ├── app-admin │ ├── routes │ │ └── frontend.routes.ts │ ├── containers │ │ ├── layout │ │ │ ├── layout.tsx │ │ │ ├── sidebar.tsx │ │ │ ├── dashboard.layout.tsx │ │ │ └── footer.tsx │ │ └── dashboard │ │ │ └── users │ │ │ └── index.tsx │ └── app.tsx ├── i18next.ts ├── types.d.ts ├── store │ ├── store.factory.ts │ └── jotai.ts ├── index.tsx └── logo.svg ├── postcss.config.js ├── .gitignore ├── .env ├── codegen.ts ├── tsconfig.json ├── index.html ├── vite.config.js ├── tailwind.config.js ├── README.md └── package.json /public/error.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/lib/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/language/lang.en.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/api/exception/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../../lib/http/exception/http.exception'; -------------------------------------------------------------------------------- /src/__generated__/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./fragment-masking"; 2 | export * from "./gql"; -------------------------------------------------------------------------------- /src/api/graphql/terminals.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../__generated__"; 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/lib/uuid/v4.ts: -------------------------------------------------------------------------------- 1 | export const uuidV4 = () => '737719f5-d398-4986-a216-8ad12fea956a'; -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/public/logo512.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/assets/images/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/images/login.jpg -------------------------------------------------------------------------------- /src/css/index.scss: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @import "ltr"; 6 | 7 | -------------------------------------------------------------------------------- /src/duck/entity/entity.model.ts: -------------------------------------------------------------------------------- 1 | export enum EntityMergeMode { 2 | REPLACE = 'replace', 3 | MERGE = 'merge' 4 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/api/config/route.config.ts: -------------------------------------------------------------------------------- 1 | export const routeConfig = { 2 | baseUrl: import.meta.env.VITE_API_BASE_URL 3 | }; 4 | -------------------------------------------------------------------------------- /src/assets/fonts/digital-7.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/fonts/digital-7.ttf -------------------------------------------------------------------------------- /src/assets/images/1120171.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/images/1120171.jpg -------------------------------------------------------------------------------- /src/assets/images/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/images/download.png -------------------------------------------------------------------------------- /src/api/config/fetch.config.ts: -------------------------------------------------------------------------------- 1 | export const fetchConfig: RequestInit = { 2 | credentials: 'include', 3 | mode: 'cors' 4 | }; -------------------------------------------------------------------------------- /src/assets/fonts/Manrope-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/fonts/Manrope-Medium.ttf -------------------------------------------------------------------------------- /src/assets/images/ec3mqt9a91j81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/images/ec3mqt9a91j81.jpg -------------------------------------------------------------------------------- /src/lib/http/mime/mime.ts: -------------------------------------------------------------------------------- 1 | export const APPLICATION_JSON = 'application/json'; 2 | export const FORM_DATA = 'multipart/form-data'; -------------------------------------------------------------------------------- /src/assets/fonts/Comfortaa-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/fonts/Comfortaa-Regular.ttf -------------------------------------------------------------------------------- /src/api/model/common.ts: -------------------------------------------------------------------------------- 1 | export interface ReactSelectOptionProps{ 2 | value: string, 3 | label: string, 4 | [key: string]: string 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/fonts/MonaspaceRadon-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ahmedali5530/pos-frontend/HEAD/src/assets/fonts/MonaspaceRadon-Medium.woff -------------------------------------------------------------------------------- /src/api/routing/url.ts: -------------------------------------------------------------------------------- 1 | import { routeConfig } from '../config/route.config'; 2 | 3 | export const url = (uri: string) => routeConfig.baseUrl + uri; -------------------------------------------------------------------------------- /src/api/model/coupn.ts: -------------------------------------------------------------------------------- 1 | import { HydraId, HydraType } from "./hydra"; 2 | 3 | export interface Coupon extends HydraId, HydraType { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/lib/http/exception/error.exception.ts: -------------------------------------------------------------------------------- 1 | export class ErrorException { 2 | 3 | constructor(public readonly error: Error) { 4 | } 5 | 6 | } 7 | -------------------------------------------------------------------------------- /src/duck/touch/touch.state.ts: -------------------------------------------------------------------------------- 1 | export interface TouchState { 2 | touch?: boolean; 3 | } 4 | 5 | export const INITIAL_STATE: TouchState = { 6 | touch: false 7 | }; 8 | -------------------------------------------------------------------------------- /src/ga.js: -------------------------------------------------------------------------------- 1 | import ReactGA from "react-ga4"; 2 | 3 | ReactGA.initialize([{ 4 | trackingId: import.meta.env.VITE_GOOGLE_ANALYTICS 5 | }]); 6 | 7 | 8 | export default ReactGA; 9 | -------------------------------------------------------------------------------- /src/duck/progress/progress.state.ts: -------------------------------------------------------------------------------- 1 | export interface ProgressState { 2 | state: string; 3 | } 4 | 5 | export const INITIAL_STATE: ProgressState = { 6 | state: 'Progress' 7 | }; 8 | -------------------------------------------------------------------------------- /src/duck/store/store.action.ts: -------------------------------------------------------------------------------- 1 | import {createAction} from 'redux-actions'; 2 | 3 | export const storeAction = createAction( 4 | 'STORE_ACTION', 5 | (payload: any) => payload 6 | ); 7 | -------------------------------------------------------------------------------- /src/duck/touch/touch.action.ts: -------------------------------------------------------------------------------- 1 | import {createAction} from 'redux-actions'; 2 | 3 | export const touchAction = createAction( 4 | 'TOUCH_ACTION', 5 | (payload: any) => payload 6 | ); 7 | -------------------------------------------------------------------------------- /src/duck/app/app.state.ts: -------------------------------------------------------------------------------- 1 | export interface AppState { 2 | hasBootstrapped: boolean; 3 | error?: Error 4 | } 5 | 6 | export const INITIAL_STATE: AppState = { 7 | hasBootstrapped: false 8 | }; -------------------------------------------------------------------------------- /src/duck/entity/entity.state.ts: -------------------------------------------------------------------------------- 1 | export interface EntityState { 2 | [entityName: string]: { 3 | [entityId: string]: object 4 | } 5 | } 6 | 7 | export const INITIAL_STATE: EntityState = {}; -------------------------------------------------------------------------------- /src/duck/auth/auth.state.ts: -------------------------------------------------------------------------------- 1 | export interface AuthState { 2 | isLoggedIn: boolean; 3 | userAccount?: string; 4 | } 5 | 6 | export const INITIAL_STATE: AuthState = { 7 | isLoggedIn: false 8 | }; -------------------------------------------------------------------------------- /src/duck/progress/progress.action.ts: -------------------------------------------------------------------------------- 1 | import {createAction} from 'redux-actions'; 2 | 3 | export const progressAction = createAction( 4 | 'PROGRESS_ACTION', 5 | (payload: any) => payload 6 | ); 7 | -------------------------------------------------------------------------------- /src/duck/terminal/terminal.action.ts: -------------------------------------------------------------------------------- 1 | import {createAction} from 'redux-actions'; 2 | 3 | export const terminalAction = createAction( 4 | 'TERMINAL_ACTION', 5 | (payload: any) => payload 6 | ); 7 | -------------------------------------------------------------------------------- /src/duck/_root/root.saga.ts: -------------------------------------------------------------------------------- 1 | import { all } from 'redux-saga/effects'; 2 | import { appSaga } from '../app/app.saga'; 3 | 4 | export function* rootSaga() { 5 | yield all([ 6 | appSaga() 7 | ]); 8 | } -------------------------------------------------------------------------------- /src/assets/images/minus.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/duck/store/store.state.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "../../api/model/store"; 2 | 3 | export interface StoreState { 4 | store?: Store; 5 | } 6 | 7 | export const INITIAL_STATE: StoreState = { 8 | store: undefined 9 | }; 10 | -------------------------------------------------------------------------------- /src/api/model/device.ts: -------------------------------------------------------------------------------- 1 | import {HydraId, HydraType} from "./hydra"; 2 | 3 | export interface Device extends HydraId, HydraType { 4 | id: string; 5 | name: string; 6 | ipAddress: string; 7 | port: string; 8 | prints: number; 9 | } 10 | -------------------------------------------------------------------------------- /src/lib/localforage/localforage.ts: -------------------------------------------------------------------------------- 1 | import localforage from "localforage"; 2 | 3 | localforage.config({ 4 | driver : localforage.INDEXEDDB, 5 | name : 'pos application', 6 | version : 1.0, 7 | }); 8 | 9 | export default localforage; -------------------------------------------------------------------------------- /src/lib/http/header/header.ts: -------------------------------------------------------------------------------- 1 | export const contentTypeHeader = (contentType: string): HeadersInit => ({ 2 | 'content-type': contentType 3 | }); 4 | 5 | export const acceptHeader = (accept: string): HeadersInit => ({ 6 | 'accept': accept 7 | }); 8 | -------------------------------------------------------------------------------- /src/api/model/brand.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Brand extends HydraId, HydraType{ 5 | id: string; 6 | name: string; 7 | stores: Store[]; 8 | isActive: boolean; 9 | } 10 | -------------------------------------------------------------------------------- /src/api/model/order.tax.ts: -------------------------------------------------------------------------------- 1 | import {Tax} from "./tax"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface OrderTax extends HydraId, HydraType { 5 | id: string; 6 | rate?: number; 7 | amount?: number; 8 | type?: Tax; 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/images/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/duck/terminal/terminal.state.ts: -------------------------------------------------------------------------------- 1 | import {Terminal} from "../../api/model/terminal"; 2 | 3 | export interface TerminalState { 4 | terminal?: Terminal; 5 | } 6 | 7 | export const INITIAL_STATE: TerminalState = { 8 | terminal: undefined 9 | }; 10 | -------------------------------------------------------------------------------- /src/duck/app/app.action.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from 'redux-actions'; 2 | 3 | export const bootstrap = createAction('BOOTSTRAP'); 4 | export const bootstrapDone = createAction('BOOTSTRAP_DONE'); 5 | export const bootstrapError = createAction('BOOTSTRAP_ERROR'); 6 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/api/model/media.ts: -------------------------------------------------------------------------------- 1 | import {HydraId, HydraType} from "./hydra"; 2 | 3 | export interface Media extends HydraId, HydraType{ 4 | id: string; 5 | name: string; 6 | originalName: string; 7 | size: number; 8 | mimeType?: string; 9 | extension?: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/api/model/tax.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Tax extends HydraId, HydraType { 5 | id: number; 6 | name: string; 7 | rate: number; 8 | stores: Store[]; 9 | isActive: boolean; 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/images/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/duck/auth/model/authorized.user.ts: -------------------------------------------------------------------------------- 1 | import {User} from "../../../api/model/user"; 2 | 3 | export interface AuthorizedUser extends User{} 4 | 5 | export function createAuthorizedUserFromApiUserAccount(userAccount: User): AuthorizedUser { 6 | return userAccount; 7 | } 8 | -------------------------------------------------------------------------------- /src/api/model/order.discount.ts: -------------------------------------------------------------------------------- 1 | import {Discount} from "./discount"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface OrderDiscount extends HydraId, HydraType { 5 | id: string; 6 | rate?: number; 7 | amount?: number; 8 | type?: Discount; 9 | } 10 | -------------------------------------------------------------------------------- /src/api/model/category.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Category extends HydraId, HydraType { 5 | id: number; 6 | name: string; 7 | type: string; 8 | isActive: boolean; 9 | stores: Store[]; 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/images/plus.svg: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/api/model/expense.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Expense extends HydraId, HydraType { 5 | id: string; 6 | description: string; 7 | amount: number; 8 | createdAt: string; 9 | store: Store; 10 | } 11 | -------------------------------------------------------------------------------- /src/api/model/order.payment.ts: -------------------------------------------------------------------------------- 1 | import {PaymentType} from "./payment.type"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface OrderPayment extends HydraId, HydraType { 5 | total: number; 6 | received: number; 7 | due: number; 8 | type?: PaymentType; 9 | } 10 | -------------------------------------------------------------------------------- /src/api/model/store.ts: -------------------------------------------------------------------------------- 1 | import {Terminal} from "./terminal"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Store extends HydraId, HydraType{ 5 | id: string; 6 | name: string; 7 | location?: string; 8 | terminals: Terminal[]; 9 | isActive: boolean 10 | } 11 | -------------------------------------------------------------------------------- /src/api/model/payment.type.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface PaymentType extends HydraId, HydraType { 5 | id: string; 6 | name: string; 7 | type: string; 8 | canHaveChangeDue?: boolean; 9 | stores: Store[]; 10 | isActive: boolean; 11 | } 12 | -------------------------------------------------------------------------------- /src/api/model/user.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface User extends HydraId, HydraType { 5 | username: string; 6 | displayName: string; 7 | id: number; 8 | email: string; 9 | roles: string[]; 10 | stores: Store[]; 11 | isActive: boolean 12 | } 13 | -------------------------------------------------------------------------------- /src/api/model/customer.payment.ts: -------------------------------------------------------------------------------- 1 | import {Order} from "./order"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface CustomerPayment extends HydraId, HydraType { 5 | id: string; 6 | amount: number; 7 | description: string; 8 | order?: Omit; 9 | createdAt: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/api/model/supplier.payment.ts: -------------------------------------------------------------------------------- 1 | import {HydraId, HydraType} from "./hydra"; 2 | import {Purchase} from "./purchase"; 3 | 4 | export interface SupplierPayment extends HydraId, HydraType{ 5 | id: string; 6 | amount: number; 7 | description?: string; 8 | createdAt: string; 9 | purchase?: Omit 10 | } 11 | -------------------------------------------------------------------------------- /src/lib/validator/validation.result.ts: -------------------------------------------------------------------------------- 1 | export interface ConstraintViolation { 2 | propertyPath: string; 3 | message: string; 4 | } 5 | 6 | export interface ValidationResult { 7 | violations: ConstraintViolation[]; 8 | errorMessage: string; 9 | code?: number; 10 | message?: string; 11 | status?: boolean; 12 | } 13 | -------------------------------------------------------------------------------- /src/duck/shortcuts/shortcut.action.ts: -------------------------------------------------------------------------------- 1 | import { createAction } from 'redux-actions'; 2 | 3 | export const shortcutAction = createAction( 4 | 'SHORTCUT_ACTION', 5 | (payload: any) => payload 6 | ); 7 | 8 | export const displayShortcutAction = createAction( 9 | 'DISPLAY_SHORTCUT_ACTION', 10 | (payload: any) => payload 11 | ) 12 | -------------------------------------------------------------------------------- /src/api/model/department.ts: -------------------------------------------------------------------------------- 1 | import {Store} from "./store"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Department extends HydraId, HydraType { 5 | id: string; 6 | name: string; 7 | description?: string; 8 | uuid: string; 9 | createdAt: {datetime: string}; 10 | updatedAt: {datetime: string}; 11 | store?: Store; 12 | } 13 | -------------------------------------------------------------------------------- /src/duck/entity/entity.schema.ts: -------------------------------------------------------------------------------- 1 | import {schema} from 'normalizr'; 2 | 3 | 4 | export const UserAccountSchema = new schema.Entity('userAccount', {}); 5 | 6 | export const StoreSchema = new schema.Entity('store', {}); 7 | 8 | export const ShortcutSchema = new schema.Entity('shortcut', {}); 9 | 10 | export const TouchSchema = new schema.Entity('touch', {}); 11 | -------------------------------------------------------------------------------- /src/api/model/product.store.ts: -------------------------------------------------------------------------------- 1 | import { HydraId, HydraType } from "./hydra"; 2 | import { Store } from "./store"; 3 | import { Product } from "./product"; 4 | 5 | export interface ProductStore extends HydraId, HydraType { 6 | id: number; 7 | store: Store; 8 | product: Product; 9 | quantity: string; 10 | location?: string; 11 | reOrderLevel?: string; 12 | } 13 | -------------------------------------------------------------------------------- /src/api/model/setting.ts: -------------------------------------------------------------------------------- 1 | import {User} from "./user"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface Setting extends HydraId, HydraType { 5 | id: string; 6 | name: string; 7 | value?: string; 8 | description?: string; 9 | type?: string; 10 | user?: User; 11 | } 12 | 13 | export enum SettingTypes { 14 | TYPE_RECEIPT = 'sale_receipt' 15 | } 16 | -------------------------------------------------------------------------------- /src/duck/shortcuts/shortcut.state.ts: -------------------------------------------------------------------------------- 1 | export interface ShortcutState { 2 | shortcut?: boolean; 3 | } 4 | 5 | export const INITIAL_STATE: ShortcutState = { 6 | shortcut: false 7 | }; 8 | 9 | export interface DisplayShortcutState { 10 | display?: boolean; 11 | } 12 | 13 | export const DISPLAY_INITIAL_STATE: DisplayShortcutState = { 14 | display: false 15 | } 16 | -------------------------------------------------------------------------------- /src/duck/store/store.selector.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import {StoreState} from "./store.state"; 3 | import {RootState} from "../_root/root.state"; 4 | 5 | export const getState = (state: RootState): StoreState => { 6 | return state.store; 7 | }; 8 | 9 | export const getStore = createSelector( 10 | [getState], state => state.store 11 | ); 12 | -------------------------------------------------------------------------------- /src/duck/touch/touch.selector.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import {TouchState} from "./touch.state"; 3 | import {RootState} from "../_root/root.state"; 4 | 5 | export const getState = (state: RootState): TouchState => { 6 | return state.touch; 7 | }; 8 | 9 | export const getTouch = createSelector( 10 | [getState], state => state.touch 11 | ); 12 | -------------------------------------------------------------------------------- /src/api/model/barcode.ts: -------------------------------------------------------------------------------- 1 | import { HydraId, HydraType } from "./hydra"; 2 | import { Product } from "./product"; 3 | import { ProductVariant } from "./product.variant"; 4 | 5 | export interface Barcode extends HydraId, HydraType { 6 | id: string; 7 | barcode: string; 8 | item: Product; 9 | variant?: ProductVariant; 10 | measurement: string; 11 | unit?: string; 12 | price?: string; 13 | } 14 | -------------------------------------------------------------------------------- /src/api/model/product.variant.ts: -------------------------------------------------------------------------------- 1 | import {ProductPrice} from "./product.price"; 2 | import {HydraId, HydraType} from "./hydra"; 3 | 4 | export interface ProductVariant extends HydraId, HydraType { 5 | id: number; 6 | name?: string; 7 | attributeName?: string; 8 | attributeValue?: string; 9 | barcode?: string; 10 | price?: number; 11 | prices?: ProductPrice[]; 12 | quantity?: number; 13 | } 14 | -------------------------------------------------------------------------------- /src/duck/progress/progress.selector.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import {ProgressState} from "./progress.state"; 3 | import {RootState} from "../_root/root.state"; 4 | 5 | export const getState = (state: RootState): ProgressState => { 6 | return state.progress; 7 | }; 8 | 9 | export const getProgress = createSelector( 10 | [getState], state => state.state 11 | ); 12 | -------------------------------------------------------------------------------- /src/lib/http/header/compose.ts: -------------------------------------------------------------------------------- 1 | export const composeHeaders = (...headersList: HeadersInit[]): Headers => { 2 | const headers = new Headers(); 3 | 4 | for (const headersListItem of headersList) { 5 | const itemHeaders = new Headers(headersListItem); 6 | 7 | itemHeaders.forEach( 8 | (value, key) => headers.append(key, value) 9 | ); 10 | } 11 | 12 | return headers; 13 | }; -------------------------------------------------------------------------------- /src/duck/terminal/terminal.selector.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect'; 2 | import {TerminalState} from "./terminal.state"; 3 | import {RootState} from "../_root/root.state"; 4 | 5 | export const getState = (state: RootState): TerminalState => { 6 | return state.terminal; 7 | }; 8 | 9 | export const getTerminal = createSelector( 10 | [getState], state => state.terminal 11 | ); 12 | -------------------------------------------------------------------------------- /src/duck/entity/selector/user.account.ts: -------------------------------------------------------------------------------- 1 | import { getEntityByIdSelector } from './_entity'; 2 | import { UserAccountSchema } from '../entity.schema'; 3 | import { WithEntityState } from '../../_root/root.state'; 4 | import {User} from "../../../api/model/user"; 5 | 6 | export const getUserAccount = (state: WithEntityState, id: string): User | undefined => getEntityByIdSelector(state, { 7 | schema: UserAccountSchema, id 8 | }); -------------------------------------------------------------------------------- /src/duck/touch/touch.reducer.ts: -------------------------------------------------------------------------------- 1 | import { Action, handleActions } from 'redux-actions'; 2 | import {INITIAL_STATE, TouchState} from "./touch.state"; 3 | import {touchAction} from "./touch.action"; 4 | 5 | export const touchReducer = handleActions({ 6 | [touchAction.toString()]: (state: TouchState, action: Action) => { 7 | return { ...state, touch: action.payload}; 8 | }, 9 | }, INITIAL_STATE); 10 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/api/request/header.ts: -------------------------------------------------------------------------------- 1 | import { acceptHeader, contentTypeHeader } from '../../lib/http/header/header'; 2 | import {APPLICATION_JSON, FORM_DATA} from '../../lib/http/mime/mime'; 3 | 4 | export const jsonContentTypeHeader = () => contentTypeHeader(APPLICATION_JSON); 5 | 6 | export const jsonAcceptHeader = () => acceptHeader(APPLICATION_JSON); 7 | 8 | export const formContentTypeHeader = () => contentTypeHeader(FORM_DATA); 9 | 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | .idea 26 | dist 27 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import type {} from 'react-select/base'; 3 | declare module 'react-select/base' { 4 | import { GroupBase } from "react-select"; 5 | 6 | export interface Props< 7 | Option, 8 | IsMulti extends boolean, 9 | Group extends GroupBase