This commit is contained in:
Thomas Peterson 2024-12-23 17:59:54 +01:00
parent 64bf731a6c
commit 8fe8f9ef16
20 changed files with 621 additions and 830 deletions

View File

@ -14,8 +14,7 @@
"imports": { "imports": {
"@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0", "@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0",
"@ebay/nice-modal-react": "npm:@ebay/nice-modal-react@^1.2.13", "@ebay/nice-modal-react": "npm:@ebay/nice-modal-react@^1.2.13",
"@preact-icons/bs": "jsr:@preact-icons/bs@^1.0.12", "@heroicons/react": "npm:@heroicons/react@^2.2.0",
"@preact-icons/ri": "jsr:@preact-icons/ri@^1.0.12",
"@rjsf/core": "npm:@rjsf/core@^5.23.2", "@rjsf/core": "npm:@rjsf/core@^5.23.2",
"@rjsf/validator-ajv6": "npm:@rjsf/validator-ajv6@^5.23.2", "@rjsf/validator-ajv6": "npm:@rjsf/validator-ajv6@^5.23.2",
"@types/react": "npm:@types/react@^18.3.12", "@types/react": "npm:@types/react@^18.3.12",
@ -28,7 +27,7 @@
"postcss": "npm:postcss@^8.4.49", "postcss": "npm:postcss@^8.4.49",
"prop-types": "npm:prop-types@^15.8.1", "prop-types": "npm:prop-types@^15.8.1",
"react": "https://esm.sh/react@18.2.0", "react": "https://esm.sh/react@18.2.0",
"react-dom": "https://esm.sh/react-dom@18.2.0", "react-dom": "https://esm.sh/react-dom@18.2.0",
"react-router-dom": "npm:react-router-dom@^7.0.2", "react-router-dom": "npm:react-router-dom@^7.0.2",
"react-select-async-paginate": "npm:react-select-async-paginate@^0.7.7", "react-select-async-paginate": "npm:react-select-async-paginate@^0.7.7",
"reflect-metadata": "npm:reflect-metadata@^0.2.2", "reflect-metadata": "npm:reflect-metadata@^0.2.2",

View File

@ -1,13 +1,11 @@
{ {
"version": "4", "version": "4",
"specifiers": { "specifiers": {
"jsr:@preact-icons/bs@^1.0.12": "1.0.12",
"jsr:@preact-icons/common@^1.0.12": "1.0.12",
"jsr:@preact-icons/ri@^1.0.12": "1.0.12",
"jsr:@std/path@1": "1.0.8", "jsr:@std/path@1": "1.0.8",
"jsr:@udibo/esbuild-plugin-postcss@~0.1.3": "0.1.3", "jsr:@udibo/esbuild-plugin-postcss@~0.1.3": "0.1.3",
"npm:@deno/vite-plugin@1": "1.0.2_vite@6.0.5", "npm:@deno/vite-plugin@1": "1.0.2_vite@6.0.5",
"npm:@ebay/nice-modal-react@^1.2.13": "1.2.13_react@18.3.1_react-dom@19.0.0__react@19.0.0", "npm:@ebay/nice-modal-react@^1.2.13": "1.2.13_react@18.3.1_react-dom@19.0.0__react@19.0.0",
"npm:@heroicons/react@^2.2.0": "2.2.0_react@18.3.1",
"npm:@rjsf/core@^5.23.2": "5.23.2_@rjsf+utils@5.23.2__react@18.3.1_react@18.3.1", "npm:@rjsf/core@^5.23.2": "5.23.2_@rjsf+utils@5.23.2__react@18.3.1_react@18.3.1",
"npm:@rjsf/validator-ajv6@^5.23.2": "5.23.2_@rjsf+utils@5.23.2__react@18.3.1_react@18.3.1", "npm:@rjsf/validator-ajv6@^5.23.2": "5.23.2_@rjsf+utils@5.23.2__react@18.3.1_react@18.3.1",
"npm:@types/react-dom@^18.3.1": "18.3.5_@types+react@18.3.18", "npm:@types/react-dom@^18.3.1": "18.3.5_@types+react@18.3.18",
@ -36,28 +34,6 @@
"npm:vite@^6.0.5": "6.0.5" "npm:vite@^6.0.5": "6.0.5"
}, },
"jsr": { "jsr": {
"@preact-icons/bs@1.0.12": {
"integrity": "52282f0e2ffc73b2828f0bdb508dec14c4867f99f9f37fc4094b39f0467d9b1f",
"dependencies": [
"jsr:@preact-icons/common",
"npm:preact@10.22.1"
]
},
"@preact-icons/common@1.0.12": {
"integrity": "f7d7329d55c2753b0162438b120b638e5058fa406f49fe6b422e3b0694f6e0c1",
"dependencies": [
"npm:@types/react",
"npm:preact@^10.22.1",
"npm:react"
]
},
"@preact-icons/ri@1.0.12": {
"integrity": "cd014a2a4bf9aea652d554d620365ea4695d4613aef1eb3833c71cad53415435",
"dependencies": [
"jsr:@preact-icons/common",
"npm:preact@10.22.1"
]
},
"@std/path@1.0.8": { "@std/path@1.0.8": {
"integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
}, },
@ -349,6 +325,12 @@
"@floating-ui/utils@0.2.8": { "@floating-ui/utils@0.2.8": {
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
}, },
"@heroicons/react@2.2.0_react@18.3.1": {
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"dependencies": [
"react@18.3.1"
]
},
"@isaacs/cliui@8.0.2": { "@isaacs/cliui@8.0.2": {
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dependencies": [ "dependencies": [
@ -1847,11 +1829,10 @@
}, },
"workspace": { "workspace": {
"dependencies": [ "dependencies": [
"jsr:@preact-icons/bs@^1.0.12",
"jsr:@preact-icons/ri@^1.0.12",
"jsr:@udibo/esbuild-plugin-postcss@~0.1.3", "jsr:@udibo/esbuild-plugin-postcss@~0.1.3",
"npm:@deno/vite-plugin@1", "npm:@deno/vite-plugin@1",
"npm:@ebay/nice-modal-react@^1.2.13", "npm:@ebay/nice-modal-react@^1.2.13",
"npm:@heroicons/react@^2.2.0",
"npm:@rjsf/core@^5.23.2", "npm:@rjsf/core@^5.23.2",
"npm:@rjsf/validator-ajv6@^5.23.2", "npm:@rjsf/validator-ajv6@^5.23.2",
"npm:@types/react-dom@^18.3.1", "npm:@types/react-dom@^18.3.1",

View File

@ -1,16 +1,33 @@
import { RiDeleteBin2Line, RiSaveFill } from "@preact-icons/ri"
import { BsXCircle, BsPlus, BsPencil } from "@preact-icons/bs"
import { Button as BaseButton } from "flowbite-react" import { Button as BaseButton } from "flowbite-react"
import React from 'react' import React from 'react'
const Button = ({ type , variant , onClick }) => { const Button = ({ type , variant , onClick }) => {
return ( return (
<BaseButton color={variant} pill onClick={onClick}> <BaseButton color={variant} pill onClick={onClick}>
{ type == 1 && <BsPlus/> } { type == 1 &&
{ type == 2 && <BsPencil/> } <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="size-6">
{ type == 3 && <RiSaveFill/> } <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"></path>
{ type == 4 && <BsXCircle/> } </svg>
{ type == 5 && <RiDeleteBin2Line/> } }
{ type == 2 &&
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125"></path>
</svg>
}
{ type == 3 &&
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" fill="none" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 20.25h12A2.25 2.25 0 0 0 20.25 18V7.5L16.5 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25zm9.75-16.5v5h-9.5v-5zM13 5.5V7m-6.75 4.25h11.5v6.5H6.25Z"></path>
</svg>
}
{ type == 4 &&
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"></path>
</svg>
}
{ type == 5 &&
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="size-6">
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"></path>
</svg> }
</BaseButton> </BaseButton>
); );
}; };

View File

@ -4,7 +4,6 @@ import OrderService from '../../services/order'
import { Component } from 'react' import { Component } from 'react'
import {debounceTime} from "rxjs" import {debounceTime} from "rxjs"
import {Order} from "../../model/order" import {Order} from "../../model/order"
import { RiSaveFill, RiPrinterFill } from "@preact-icons/ri"
import { Button } from "flowbite-react" import { Button } from "flowbite-react"
import React from 'react' import React from 'react'
@ -54,10 +53,14 @@ class ButtonComponent extends Component<{loadOrder},{disabled: boolean}> {
return ( return (
<div className="flex gap-3"> <div className="flex gap-3">
<Button size="xs" color="info" disabled={this.state.disabled} onClick={(e:any) => this.handleSave(e)}> <Button size="xs" color="info" disabled={this.state.disabled} onClick={(e:any) => this.handleSave(e)}>
<div className="mr-2 h-5 w-5"/> Speichern <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" fill="none" class="mr-2 h-5 w-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 20.25h12A2.25 2.25 0 0 0 20.25 18V7.5L16.5 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25zm9.75-16.5v5h-9.5v-5zM13 5.5V7m-6.75 4.25h11.5v6.5H6.25Z"></path>
</svg> Speichern
</Button> </Button>
<Button size="xs" color="success" disabled={!this.orderState.getCurrentOrder().value.saved} onClick={(e:any) => this.handlePrint(e)}> <Button size="xs" color="success" disabled={!this.orderState.getCurrentOrder().value.saved} onClick={(e:any) => this.handlePrint(e)}>
<div className="mr-2 h-5 w-5"/> Drucken <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true" data-slot="icon" class="mr-2 h-5 w-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.72 13.829c-.24.03-.48.062-.72.096m.72-.096a42.415 42.415 0 0 1 10.56 0m-10.56 0L6.34 18m10.94-4.171c.24.03.48.062.72.096m-.72-.096L17.66 18m0 0 .229 2.523a1.125 1.125 0 0 1-1.12 1.227H7.231c-.662 0-1.18-.568-1.12-1.227L6.34 18m11.318 0h1.091A2.25 2.25 0 0 0 21 15.75V9.456c0-1.081-.768-2.015-1.837-2.175a48.055 48.055 0 0 0-1.913-.247M6.34 18H5.25A2.25 2.25 0 0 1 3 15.75V9.456c0-1.081.768-2.015 1.837-2.175a48.041 48.041 0 0 1 1.913-.247m10.5 0a48.536 48.536 0 0 0-10.5 0m10.5 0V3.375c0-.621-.504-1.125-1.125-1.125h-8.25c-.621 0-1.125.504-1.125 1.125v3.659M18 10.5h.008v.008H18V10.5Zm-3 0h.008v.008H15V10.5Z"></path>
</svg> Drucken
</Button> </Button>
</div> </div>
) )

View File

@ -7,7 +7,7 @@ import {useEffect, useState} from "react"
import {Pos} from "../../model/pos" import {Pos} from "../../model/pos"
import Order from "../../model/order" import Order from "../../model/order"
import OrderState from "../../state/order" import OrderState from "../../state/order"
import {container} from "tsyringe-neo"
const PositionsComponent = ({order, shop, updateOrder}) => { const PositionsComponent = ({order, shop, updateOrder}) => {
const orderState = container.resolve(OrderState) const orderState = container.resolve(OrderState)

View File

@ -10,11 +10,8 @@ const ShopSelectComponent = (props) => {
const orderState = container.resolve(OrderState) const orderState = container.resolve(OrderState)
const shop_service = container.resolve(ShopService) const shop_service = container.resolve(ShopService)
const token_service = container.resolve(Token)
const loadOptions = async (searchQuery, loadedOptions) => { const loadOptions = async (searchQuery, loadedOptions) => {
console.log(token_service)
const data = await shop_service.getShops() const data = await shop_service.getShops()
return { return {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo"; import {inject, autoInjectable, singleton} from "tsyringe-neo";
import { Token } from "./token"; import Token from "./token";
import axios from 'axios'; import axios from 'axios';
import { Account } from "../model/account"; import { Account } from "../model/account";
import { Shop } from "../model/shop"; import { Shop } from "../model/shop";
@ -7,7 +7,9 @@ import { Shop } from "../model/shop";
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class AccountService { class AccountService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getAccounts(shop: Shop): Promise<Account[]> { async getAccounts(shop: Shop): Promise<Account[]> {

View File

@ -1,12 +1,14 @@
import {autoInjectable, singleton} from "tsyringe-neo" import {inject, autoInjectable, singleton} from "tsyringe-neo"
import { Token } from "./token" import Token from "./token"
import axios from 'axios' import axios from 'axios'
import { Address } from "../model/address" import { Address } from "../model/address"
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class AddressService { class AddressService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async create(address: Address): Promise<Address> { async create(address: Address): Promise<Address> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo"; import {inject, autoInjectable, singleton} from "tsyringe-neo";
import { Token } from "./token"; import Token from "./token";
import axios from 'axios'; import axios from 'axios';
import { Contact } from "../model/contact"; import { Contact } from "../model/contact";
import { Address } from "../model/address"; import { Address } from "../model/address";
@ -8,7 +8,9 @@ import { Shop } from "../model/shop";
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class ContactService { class ContactService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async createContact(contact: Contact): Promise<Contact> { async createContact(contact: Contact): Promise<Contact> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo"; import {inject, autoInjectable, singleton} from "tsyringe-neo";
import { Token } from "./token"; import Token from "./token";
import axios from 'axios'; import axios from 'axios';
import Order from "../model/order"; import Order from "../model/order";
@ -7,7 +7,9 @@ import Order from "../model/order";
@autoInjectable() @autoInjectable()
class OrderService { class OrderService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getOrder(uuid: String): Promise<Order> { async getOrder(uuid: String): Promise<Order> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo" import {inject, autoInjectable, singleton} from "tsyringe-neo"
import { Token } from "./token" import Token from "./token"
import axios from 'axios' import axios from 'axios'
import { Shop } from "../model/shop" import { Shop } from "../model/shop"
import {Payment} from "../model/payment" import {Payment} from "../model/payment"
@ -7,7 +7,9 @@ import {Payment} from "../model/payment"
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class PaymentService { class PaymentService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getPayments(shop: Shop): Promise<Payment[]> { async getPayments(shop: Shop): Promise<Payment[]> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo"; import {inject, autoInjectable, singleton} from "tsyringe-neo";
import { Token } from "./token"; import Token from "./token";
import axios from 'axios'; import axios from 'axios';
import { Shop } from "../model/shop"; import { Shop } from "../model/shop";
import {ProductGroup} from "../model/productGroup"; import {ProductGroup} from "../model/productGroup";
@ -9,7 +9,9 @@ import {JSONSchema7} from "json-schema";
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class ProductService { class ProductService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getProductsByTerm(term: string, shop: Shop): Promise<Product[]> { async getProductsByTerm(term: string, shop: Shop): Promise<Product[]> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo"; import {inject, autoInjectable, singleton} from "tsyringe-neo";
import { Token } from "./token"; import Token from "./token";
import axios from 'axios'; import axios from 'axios';
import { Shop } from "../model/shop"; import { Shop } from "../model/shop";
import {ProductGroup} from "../model/productGroup"; import {ProductGroup} from "../model/productGroup";
@ -7,7 +7,9 @@ import {ProductGroup} from "../model/productGroup";
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class ProductGroupService { class ProductGroupService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getProductGroups(searchQuery: String, shop: Shop): Promise<ProductGroup[]> { async getProductGroups(searchQuery: String, shop: Shop): Promise<ProductGroup[]> {

View File

@ -1,5 +1,5 @@
import {autoInjectable, singleton} from "tsyringe-neo" import {inject, autoInjectable, singleton} from "tsyringe-neo"
import { Token } from "./token" import Token from "./token"
import axios from 'axios' import axios from 'axios'
import { Shop } from "../model/shop" import { Shop } from "../model/shop"
import {Shipping} from "../model/shipping" import {Shipping} from "../model/shipping"
@ -7,8 +7,9 @@ import {Shipping} from "../model/shipping"
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class ShippingService { class ShippingService {
constructor(private token?: Token) {} constructor(@inject(Token) token?: Token) {
this.token = token
}
async getShipping(shop: Shop): Promise<Shipping[]> { async getShipping(shop: Shop): Promise<Shipping[]> {
return await axios.get('/apps/api/shipping/by/shop/' + shop.uuid, { return await axios.get('/apps/api/shipping/by/shop/' + shop.uuid, {

View File

@ -1,13 +1,14 @@
import {autoInjectable, singleton} from "tsyringe-neo" import {autoInjectable, inject, singleton} from "tsyringe-neo"
import { Token } from "./token" import Token from "./token"
import axios from 'axios' import axios from 'axios'
import { Shop } from "../model/shop" import { Shop } from "../model/shop"
@singleton() @singleton()
@autoInjectable() @autoInjectable()
class ShopService { class ShopService {
constructor(token?: Token) {
console.log(token) constructor(@inject(Token) token?: Token) {
this.token = token
} }
async getShops(): Promise<Shop[]> { async getShops(): Promise<Shop[]> {

View File

@ -1,5 +1,5 @@
import axios from "axios" import axios from "axios"
import {singleton} from "tsyringe-neo" import {singleton, injectable} from "tsyringe-neo"
@singleton() @singleton()
class Token { class Token {

View File

@ -1,6 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES2020", "target": "ES2020",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"], "lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",

View File

@ -4,7 +4,8 @@
"lib": ["ES2023"], "lib": ["ES2023"],
"module": "ESNext", "module": "ESNext",
"skipLibCheck": true, "skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
"allowImportingTsExtensions": true, "allowImportingTsExtensions": true,

View File

@ -1251,6 +1251,10 @@ input[type="range"]::-ms-fill-lower {
.hidden { .hidden {
display: none; display: none;
} }
.size-6 {
width: 1.5rem;
height: 1.5rem;
}
.h-0\.5 { .h-0\.5 {
height: 0.125rem; height: 0.125rem;
} }

File diff suppressed because one or more lines are too long