diff --git a/.gitignore b/.gitignore
index 28b81ce..576a970 100644
--- a/.gitignore
+++ b/.gitignore
@@ -125,6 +125,8 @@ dist
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+yarn.lock
+package-lock.json
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
@@ -148,3 +150,7 @@ yarn-error.log*
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+
+# IDE settings
+settings.json
+launch.json
diff --git a/package.json b/package.json
index 41974dc..7fd01ea 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"@types/react-table": "^7.0.25",
"@types/yup": "^0.29.9",
"firebase": "^8.4.3",
+ "dinero.js": "^1.8.1",
"formik": "^2.2.3",
"framer-motion": "^2.6.15",
"graphql": "^15.3.0",
@@ -64,6 +65,7 @@
"@graphql-codegen/typescript": "1.19.0",
"@graphql-codegen/typescript-operations": "1.17.13",
"@graphql-codegen/typescript-react-apollo": "2.2.1",
+ "@types/dinero.js": "^1.6.5",
"@typescript-eslint/eslint-plugin": "^4.11.1",
"@typescript-eslint/parser": "^4.11.1",
"eslint-config-prettier": "^7.1.0",
@@ -79,4 +81,4 @@
"pre-commit": "yarn lint && yarn test:ci"
}
}
-}
+}
\ No newline at end of file
diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx
index fcb2e8e..1ed3e45 100644
--- a/src/components/layout/Sidebar.tsx
+++ b/src/components/layout/Sidebar.tsx
@@ -59,7 +59,7 @@ const Sidebar: React.FC = () => {
window.location.reload();
}}
>
-
+
diff --git a/src/generated/graphql.ts b/src/generated/graphql.ts
index 78cb684..17b0e38 100644
--- a/src/generated/graphql.ts
+++ b/src/generated/graphql.ts
@@ -19,105 +19,6 @@ export type Scalars = {
DateTime: any;
};
-export type Query = {
- __typename?: 'Query';
- tenants: TenantsListResponse;
- tenant: Tenant;
- categories: CategoriesListResponse;
- category: Category;
- products: ProductsListResponse;
- product: Product;
- prices: PricesListResponse;
- price: Price;
- variants: VariantsListResponse;
- variant: Variant;
- attributes: AttributesListResponse;
- attribute: Attribute;
- signedUrl: SignedUrl;
-};
-
-export type QueryTenantArgs = {
- id: Scalars['Int'];
-};
-
-export type QueryCategoryArgs = {
- id: Scalars['Int'];
-};
-
-export type QueryProductArgs = {
- id: Scalars['Int'];
-};
-
-export type QueryPriceArgs = {
- id: Scalars['Int'];
-};
-
-export type QueryVariantArgs = {
- id: Scalars['Int'];
-};
-
-export type QueryAttributeArgs = {
- id: Scalars['Int'];
-};
-
-export type QuerySignedUrlArgs = {
- input: QuerySignedUrlInput;
-};
-
-export type TenantsListResponse = {
- __typename?: 'TenantsListResponse';
- items: Array;
-};
-
-export type Tenant = {
- __typename?: 'Tenant';
- id: Scalars['Int'];
- status: TenantStatus;
- priceDisplay: TenantPriceDisplay;
- title: Scalars['String'];
- displayName: Scalars['String'];
- url: Scalars['String'];
- languageCode: Scalars['String'];
- createdAt: Scalars['DateTime'];
- updatedAt: Scalars['DateTime'];
- emailAddresses: Array;
- addresses: Array;
- socialMedias: Array;
- trackingTags: Array;
- storeUrls: Array;
-};
-
-export enum TenantStatus {
- TenantStatusUnspecified = 'TENANT_STATUS_UNSPECIFIED',
- Pending = 'PENDING',
- Active = 'ACTIVE',
- Inactive = 'INACTIVE',
-}
-
-export enum TenantPriceDisplay {
- IncVat = 'INC_VAT',
- ExlVat = 'EXL_VAT',
-}
-
-export type EmailAddress = {
- __typename?: 'EmailAddress';
- id: Scalars['Int'];
- type: EmailAddressType;
- address: Scalars['String'];
- tenantId: Scalars['Int'];
- tenant: Tenant;
-};
-
-export enum EmailAddressType {
- EmailAddressTypeUnspecified = 'EMAIL_ADDRESS_TYPE_UNSPECIFIED',
- Primary = 'PRIMARY',
- CatchAll = 'CATCH_ALL',
- Order = 'ORDER',
- Announcement = 'ANNOUNCEMENT',
- Recovery = 'RECOVERY',
- CustomerFacing = 'CUSTOMER_FACING',
-}
-
export type Address = {
__typename?: 'Address';
id: Scalars['Int'];
@@ -132,8 +33,6 @@ export type Address = {
recipients: Scalars['String'];
organization: Scalars['String'];
current: Scalars['String'];
- tenantId: Scalars['Int'];
- tenant: Tenant;
};
export enum AddressType {
@@ -143,59 +42,51 @@ export enum AddressType {
Visitor = 'VISITOR',
}
-export type SocialMedia = {
- __typename?: 'SocialMedia';
+export type Attachment = {
+ __typename?: 'Attachment';
id: Scalars['Int'];
- type: SocialMediaType;
url: Scalars['String'];
- tenantId: Scalars['Int'];
- tenant: Tenant;
+ mime?: Maybe;
+ size: Scalars['Int'];
};
-export enum SocialMediaType {
- SocialMediaTypeUnspecified = 'SOCIAL_MEDIA_TYPE_UNSPECIFIED',
- Facebook = 'FACEBOOK',
- Twitter = 'TWITTER',
- Googleplus = 'GOOGLEPLUS',
- Instagram = 'INSTAGRAM',
- Linkedin = 'LINKEDIN',
- Pinterest = 'PINTEREST',
- Other = 'OTHER',
-}
+export type AttachmentCreateInput = {
+ url: Scalars['String'];
+ mime: Scalars['String'];
+ size: Scalars['Int'];
+};
-export type TrackingTag = {
- __typename?: 'TrackingTag';
+export type AttachmentsListResponse = {
+ __typename?: 'AttachmentsListResponse';
+ items: Array;
+};
+
+export type Attribute = {
+ __typename?: 'Attribute';
id: Scalars['Int'];
- type: TrackingTagType;
+ name: Scalars['String'];
+ displayName: Scalars['String'];
value: Scalars['String'];
- tenantId: Scalars['Int'];
- tenant: Tenant;
+ product: Product;
+ variant?: Maybe;
};
-export enum TrackingTagType {
- TrackingTagTypeUnspecified = 'TRACKING_TAG_TYPE_UNSPECIFIED',
- GoogleAnalytics = 'GOOGLE_ANALYTICS',
- GoogleTagManager = 'GOOGLE_TAG_MANAGER',
- FacebookPixel = 'FACEBOOK_PIXEL',
- Hubspot = 'HUBSPOT',
- Other = 'OTHER',
-}
+export type AttributeCreateInput = {
+ name: Scalars['String'];
+ displayName: Scalars['String'];
+ value: Scalars['String'];
+};
-export type StoreUrl = {
- __typename?: 'StoreUrl';
- id: Scalars['Int'];
- type: StoreUrlType;
- url: Scalars['String'];
- tenantId: Scalars['Int'];
- tenant: Tenant;
+export type AttributeUpdateInput = {
+ name: Scalars['String'];
+ displayName: Scalars['String'];
+ value: Scalars['String'];
};
-export enum StoreUrlType {
- StoreUrlTypeUnspecified = 'STORE_URL_TYPE_UNSPECIFIED',
- CancellationForm = 'CANCELLATION_FORM',
- TermsAndConditions = 'TERMS_AND_CONDITIONS',
- PrivacyAgreement = 'PRIVACY_AGREEMENT',
-}
+export type AttributesListResponse = {
+ __typename?: 'AttributesListResponse';
+ items: Array;
+};
export type CategoriesListResponse = {
__typename?: 'CategoriesListResponse';
@@ -215,129 +106,188 @@ export type Category = {
products?: Maybe>;
};
+export type CategoryCreateInput = {
+ status: CategoryStatus;
+ title: Scalars['String'];
+ showInMainMenu?: Maybe;
+ parentId?: Maybe;
+ tenantId: Scalars['Int'];
+};
+
export enum CategoryStatus {
CategoryStatusUnspecified = 'CATEGORY_STATUS_UNSPECIFIED',
Active = 'ACTIVE',
Inactive = 'INACTIVE',
}
-export type Product = {
- __typename?: 'Product';
- id: Scalars['Int'];
+export type CategoryUpdateInput = {
+ status: CategoryStatus;
title: Scalars['String'];
- slug?: Maybe;
- isOnMainPage?: Maybe;
- shortDescription?: Maybe;
- description?: Maybe;
- technicalDescription?: Maybe;
- isAvailable?: Maybe;
- count?: Maybe;
- status: ProductStatus;
- priceId?: Maybe;
+ showInMainMenu?: Maybe;
+ parentId?: Maybe;
tenantId: Scalars['Int'];
- stockControl?: Maybe;
- inStockNum?: Maybe;
- price?: Maybe;
- categories: Array;
- attributes: Array;
- variants: Array;
- images: Array;
};
-export enum ProductStatus {
- ProductStatusUnspecified = 'PRODUCT_STATUS_UNSPECIFIED',
- Pending = 'PENDING',
- Active = 'ACTIVE',
- Inactive = 'INACTIVE',
+/** Currency Code */
+export enum CurrencyCode {
+ Usd = 'USD',
+ Cad = 'CAD',
+ Eur = 'EUR',
+ Aed = 'AED',
+ Afn = 'AFN',
+ All = 'ALL',
+ Amd = 'AMD',
+ Ars = 'ARS',
+ Aud = 'AUD',
+ Azn = 'AZN',
+ Bam = 'BAM',
+ Bdt = 'BDT',
+ Bgn = 'BGN',
+ Bhd = 'BHD',
+ Bif = 'BIF',
+ Bnd = 'BND',
+ Bob = 'BOB',
+ Brl = 'BRL',
+ Bwp = 'BWP',
+ Byn = 'BYN',
+ Bzd = 'BZD',
+ Cdf = 'CDF',
+ Chf = 'CHF',
+ Clp = 'CLP',
+ Cny = 'CNY',
+ Cop = 'COP',
+ Crc = 'CRC',
+ Cve = 'CVE',
+ Czk = 'CZK',
+ Djf = 'DJF',
+ Dkk = 'DKK',
+ Dop = 'DOP',
+ Dzd = 'DZD',
+ Eek = 'EEK',
+ Egp = 'EGP',
+ Ern = 'ERN',
+ Etb = 'ETB',
+ Gbp = 'GBP',
+ Gel = 'GEL',
+ Ghs = 'GHS',
+ Gnf = 'GNF',
+ Gtq = 'GTQ',
+ Hkd = 'HKD',
+ Hnl = 'HNL',
+ Hrk = 'HRK',
+ Huf = 'HUF',
+ Idr = 'IDR',
+ Ils = 'ILS',
+ Inr = 'INR',
+ Iqd = 'IQD',
+ Irr = 'IRR',
+ Isk = 'ISK',
+ Jmd = 'JMD',
+ Jod = 'JOD',
+ Jpy = 'JPY',
+ Kes = 'KES',
+ Khr = 'KHR',
+ Kmf = 'KMF',
+ Krw = 'KRW',
+ Kwd = 'KWD',
+ Kzt = 'KZT',
+ Lbp = 'LBP',
+ Lkr = 'LKR',
+ Ltl = 'LTL',
+ Lvl = 'LVL',
+ Lyd = 'LYD',
+ Mad = 'MAD',
+ Mdl = 'MDL',
+ Mga = 'MGA',
+ Mkd = 'MKD',
+ Mmk = 'MMK',
+ Mop = 'MOP',
+ Mur = 'MUR',
+ Mxn = 'MXN',
+ Myr = 'MYR',
+ Mzn = 'MZN',
+ Nad = 'NAD',
+ Ngn = 'NGN',
+ Nio = 'NIO',
+ Nok = 'NOK',
+ Npr = 'NPR',
+ Nzd = 'NZD',
+ Omr = 'OMR',
+ Pab = 'PAB',
+ Pen = 'PEN',
+ Php = 'PHP',
+ Pkr = 'PKR',
+ Pln = 'PLN',
+ Pyg = 'PYG',
+ Qar = 'QAR',
+ Ron = 'RON',
+ Rsd = 'RSD',
+ Rub = 'RUB',
+ Rwf = 'RWF',
+ Sar = 'SAR',
+ Sdg = 'SDG',
+ Sek = 'SEK',
+ Sgd = 'SGD',
+ Sos = 'SOS',
+ Syp = 'SYP',
+ Thb = 'THB',
+ Tnd = 'TND',
+ Top = 'TOP',
+ Try = 'TRY',
+ Ttd = 'TTD',
+ Twd = 'TWD',
+ Tzs = 'TZS',
+ Uah = 'UAH',
+ Ugx = 'UGX',
+ Uyu = 'UYU',
+ Uzs = 'UZS',
+ Vef = 'VEF',
+ Vnd = 'VND',
+ Xaf = 'XAF',
+ Xof = 'XOF',
+ Yer = 'YER',
+ Zar = 'ZAR',
+ Zmk = 'ZMK',
+ Zwl = 'ZWL',
}
-export type Price = {
- __typename?: 'Price';
- id: Scalars['Int'];
- value: Scalars['Int'];
- product?: Maybe;
- vatRateId?: Maybe;
- vatRate?: Maybe;
- productId?: Maybe;
- formatted: FormattedPrice;
-};
-
-export type VatRate = {
- __typename?: 'VatRate';
+export type EmailAddress = {
+ __typename?: 'EmailAddress';
id: Scalars['Int'];
- value: Scalars['Int'];
+ type: EmailAddressType;
+ address: Scalars['String'];
tenantId: Scalars['Int'];
+ tenant: Tenant;
};
-export type FormattedPrice = {
- __typename?: 'FormattedPrice';
- vatAmount?: Maybe;
- grossAmount: Scalars['Int'];
- netAmount: Scalars['Int'];
-};
-
-export type Attribute = {
- __typename?: 'Attribute';
- id: Scalars['Int'];
- name: Scalars['String'];
- displayName: Scalars['String'];
- value: Scalars['String'];
- product: Product;
- variant?: Maybe;
-};
-
-export type Variant = {
- __typename?: 'Variant';
- id: Scalars['Int'];
- name: Scalars['String'];
- displayName: Scalars['String'];
- count?: Maybe;
- priceId?: Maybe;
- price?: Maybe;
- productId?: Maybe;
- product?: Maybe;
- attributes?: Maybe>;
-};
+export enum EmailAddressType {
+ EmailAddressTypeUnspecified = 'EMAIL_ADDRESS_TYPE_UNSPECIFIED',
+ Primary = 'PRIMARY',
+ CatchAll = 'CATCH_ALL',
+ Order = 'ORDER',
+ Announcement = 'ANNOUNCEMENT',
+ Recovery = 'RECOVERY',
+ CustomerFacing = 'CUSTOMER_FACING',
+}
-export type Attachment = {
- __typename?: 'Attachment';
- id: Scalars['Int'];
+export type ImageCreateInput = {
+ id?: Maybe;
url: Scalars['String'];
mime?: Maybe;
- size: Scalars['Int'];
-};
-
-export type ProductsListResponse = {
- __typename?: 'ProductsListResponse';
- items: Array;
-};
-
-export type PricesListResponse = {
- __typename?: 'PricesListResponse';
- items: Array;
-};
-
-export type VariantsListResponse = {
- __typename?: 'VariantsListResponse';
- items: Array;
+ size?: Maybe;
};
-export type AttributesListResponse = {
- __typename?: 'AttributesListResponse';
- items: Array;
+export type Money = {
+ __typename?: 'Money';
+ amount: Scalars['Int'];
+ currency?: Maybe;
+ precision?: Maybe;
};
-export type SignedUrl = {
- __typename?: 'SignedUrl';
- url: Scalars['String'];
- expires: Scalars['String'];
- accessUrl: Scalars['String'];
-};
-
-export type QuerySignedUrlInput = {
- filename: Scalars['String'];
- contentType: Scalars['String'];
- contentLength: Scalars['Int'];
+export type MoneyInput = {
+ amount: Scalars['Int'];
+ currency?: Maybe;
+ precision?: Maybe;
};
export type Mutation = {
@@ -351,9 +301,6 @@ export type Mutation = {
createProduct: Product;
updateProduct: Product;
deleteProduct: Scalars['Boolean'];
- createPrice: Price;
- updatePrice: Price;
- deletePrice: Scalars['Boolean'];
createVariant: Variant;
updateVariant: Variant;
deleteVariant: Scalars['Boolean'];
@@ -372,77 +319,259 @@ export type MutationUpdateTenantArgs = {
id: Scalars['Int'];
};
-export type MutationDeleteTenantArgs = {
- id: Scalars['Int'];
+export type MutationDeleteTenantArgs = {
+ id: Scalars['Int'];
+};
+
+export type MutationCreateCategoryArgs = {
+ input: CategoryCreateInput;
+};
+
+export type MutationUpdateCategoryArgs = {
+ input: CategoryUpdateInput;
+ id: Scalars['Int'];
+};
+
+export type MutationDeleteCategoryArgs = {
+ id: Scalars['Int'];
+};
+
+export type MutationCreateProductArgs = {
+ input: ProductCreateInput;
+};
+
+export type MutationUpdateProductArgs = {
+ input: ProductUpdateInput;
+ id: Scalars['Int'];
+};
+
+export type MutationDeleteProductArgs = {
+ id: Scalars['Int'];
+};
+
+export type MutationCreateVariantArgs = {
+ input: VariantCreateInput;
+};
+
+export type MutationUpdateVariantArgs = {
+ input: VariantUpdateInput;
+ id: Scalars['Int'];
+};
+
+export type MutationDeleteVariantArgs = {
+ id: Scalars['Int'];
+};
+
+export type MutationCreateAttributeArgs = {
+ input: AttributeCreateInput;
+};
+
+export type MutationUpdateAttributeArgs = {
+ input: AttributeUpdateInput;
+ id: Scalars['Int'];
+};
+
+export type MutationDeleteAttributeArgs = {
+ id: Scalars['Int'];
+};
+
+export type MutationCreateAttachmentsArgs = {
+ input: Array;
+};
+
+export type Price = {
+ __typename?: 'Price';
+ vatAmount: Money;
+ grossAmount: Money;
+ netAmount: Money;
+};
+
+export type PriceInput = {
+ grossAmount: MoneyInput;
+};
+
+export type Product = {
+ __typename?: 'Product';
+ id: Scalars['Int'];
+ title: Scalars['String'];
+ slug?: Maybe;
+ isOnMainPage?: Maybe;
+ shortDescription?: Maybe;
+ description?: Maybe;
+ technicalDescription?: Maybe;
+ isAvailable?: Maybe;
+ count?: Maybe;
+ status: ProductStatus;
+ tenantId: Scalars['Int'];
+ stockControl?: Maybe;
+ inStockNum?: Maybe;
+ price?: Maybe;
+ vatRate?: Maybe;
+ categories: Array;
+ attributes: Array;
+ variants: Array;
+ images: Array;
+};
+
+export type ProductCategoryCreateInput = {
+ id?: Maybe;
+ title: Scalars['String'];
+};
+
+export type ProductCreateInput = {
+ title: Scalars['String'];
+ slug?: Maybe;
+ isOnMainPage: Scalars['Boolean'];
+ shortDescription?: Maybe;
+ description?: Maybe;
+ technicalDescription?: Maybe;
+ isAvailable?: Maybe;
+ count?: Maybe;
+ status: ProductStatus;
+ tenantId: Scalars['Int'];
+ stockControl?: Maybe;
+ inStockNum?: Maybe;
+ price?: Maybe;
+ vatRateId?: Maybe;
+ categories?: Maybe>;
+ images?: Maybe>;
+};
+
+export enum ProductStatus {
+ ProductStatusUnspecified = 'PRODUCT_STATUS_UNSPECIFIED',
+ Pending = 'PENDING',
+ Active = 'ACTIVE',
+ Inactive = 'INACTIVE',
+}
+
+export type ProductUpdateInput = {
+ title: Scalars['String'];
+ slug?: Maybe;
+ isOnMainPage: Scalars['Boolean'];
+ shortDescription?: Maybe;
+ description?: Maybe;
+ technicalDescription?: Maybe;
+ isAvailable?: Maybe;
+ count?: Maybe;
+ status: ProductStatus;
+ tenantId: Scalars['Int'];
+ stockControl?: Maybe;
+ inStockNum?: Maybe;
+ price?: Maybe;
+ vatRateId?: Maybe;
+ categories?: Maybe>;
+ images?: Maybe>;
+};
+
+export type ProductsListResponse = {
+ __typename?: 'ProductsListResponse';
+ items: Array;
};
-export type MutationCreateCategoryArgs = {
- input: CategoryCreateInput;
+export type Query = {
+ __typename?: 'Query';
+ tenants: TenantsListResponse;
+ tenant: Tenant;
+ categories: CategoriesListResponse;
+ category: Category;
+ products: ProductsListResponse;
+ product: Product;
+ variants: VariantsListResponse;
+ variant: Variant;
+ attributes: AttributesListResponse;
+ attribute: Attribute;
+ signedUrl: SignedUrl;
};
-export type MutationUpdateCategoryArgs = {
- input: CategoryUpdateInput;
+export type QueryTenantArgs = {
id: Scalars['Int'];
};
-export type MutationDeleteCategoryArgs = {
+export type QueryCategoryArgs = {
id: Scalars['Int'];
};
-export type MutationCreateProductArgs = {
- input: ProductCreateInput;
-};
-
-export type MutationUpdateProductArgs = {
- input: ProductUpdateInput;
+export type QueryProductArgs = {
id: Scalars['Int'];
};
-export type MutationDeleteProductArgs = {
+export type QueryVariantArgs = {
id: Scalars['Int'];
};
-export type MutationCreatePriceArgs = {
- input: PriceCreateInput;
-};
-
-export type MutationUpdatePriceArgs = {
- input: PriceUpdateInput;
+export type QueryAttributeArgs = {
id: Scalars['Int'];
};
-export type MutationDeletePriceArgs = {
- id: Scalars['Int'];
+export type QuerySignedUrlArgs = {
+ input: QuerySignedUrlInput;
};
-export type MutationCreateVariantArgs = {
- input: VariantCreateInput;
+export type QuerySignedUrlInput = {
+ filename: Scalars['String'];
+ contentType: Scalars['String'];
+ contentLength: Scalars['Int'];
};
-export type MutationUpdateVariantArgs = {
- input: VariantUpdateInput;
- id: Scalars['Int'];
+export type SignedUrl = {
+ __typename?: 'SignedUrl';
+ url: Scalars['String'];
+ expires: Scalars['String'];
+ accessUrl: Scalars['String'];
};
-export type MutationDeleteVariantArgs = {
+export type SocialMedia = {
+ __typename?: 'SocialMedia';
id: Scalars['Int'];
+ type: SocialMediaType;
+ url: Scalars['String'];
+ tenantId: Scalars['Int'];
+ tenant: Tenant;
};
-export type MutationCreateAttributeArgs = {
- input: AttributeCreateInput;
-};
+export enum SocialMediaType {
+ SocialMediaTypeUnspecified = 'SOCIAL_MEDIA_TYPE_UNSPECIFIED',
+ Facebook = 'FACEBOOK',
+ Twitter = 'TWITTER',
+ Googleplus = 'GOOGLEPLUS',
+ Instagram = 'INSTAGRAM',
+ Linkedin = 'LINKEDIN',
+ Pinterest = 'PINTEREST',
+ Other = 'OTHER',
+}
-export type MutationUpdateAttributeArgs = {
- input: AttributeUpdateInput;
+export type StoreUrl = {
+ __typename?: 'StoreUrl';
id: Scalars['Int'];
+ type: StoreUrlType;
+ url: Scalars['String'];
+ tenantId: Scalars['Int'];
+ tenant: Tenant;
};
-export type MutationDeleteAttributeArgs = {
- id: Scalars['Int'];
-};
+export enum StoreUrlType {
+ StoreUrlTypeUnspecified = 'STORE_URL_TYPE_UNSPECIFIED',
+ CancellationForm = 'CANCELLATION_FORM',
+ TermsAndConditions = 'TERMS_AND_CONDITIONS',
+ PrivacyAgreement = 'PRIVACY_AGREEMENT',
+}
-export type MutationCreateAttachmentsArgs = {
- input: Array;
+export type Tenant = {
+ __typename?: 'Tenant';
+ id: Scalars['Int'];
+ status: TenantStatus;
+ priceDisplay: TenantPriceDisplay;
+ title: Scalars['String'];
+ displayName: Scalars['String'];
+ url: Scalars['String'];
+ languageCode: Scalars['String'];
+ createdAt: Scalars['DateTime'];
+ updatedAt: Scalars['DateTime'];
+ emailAddresses: Array;
+ addresses: Array;
+ socialMedias: Array;
+ trackingTags: Array;
+ storeUrls: Array;
};
export type TenantCreateInput = {
@@ -454,6 +583,18 @@ export type TenantCreateInput = {
languageCode?: Maybe;
};
+export enum TenantPriceDisplay {
+ IncVat = 'INC_VAT',
+ ExlVat = 'EXL_VAT',
+}
+
+export enum TenantStatus {
+ TenantStatusUnspecified = 'TENANT_STATUS_UNSPECIFIED',
+ Pending = 'PENDING',
+ Active = 'ACTIVE',
+ Inactive = 'INACTIVE',
+}
+
export type TenantUpdateInput = {
status: Scalars['String'];
priceDisplay: Scalars['String'];
@@ -463,87 +604,44 @@ export type TenantUpdateInput = {
languageCode?: Maybe;
};
-export type CategoryCreateInput = {
- status: CategoryStatus;
- title: Scalars['String'];
- showInMainMenu?: Maybe;
- parentId?: Maybe;
- tenantId: Scalars['Int'];
-};
-
-export type CategoryUpdateInput = {
- status: CategoryStatus;
- title: Scalars['String'];
- showInMainMenu?: Maybe;
- parentId?: Maybe;
- tenantId: Scalars['Int'];
+export type TenantsListResponse = {
+ __typename?: 'TenantsListResponse';
+ items: Array;
};
-export type ProductCreateInput = {
- title: Scalars['String'];
- slug?: Maybe;
- isOnMainPage: Scalars['Boolean'];
- shortDescription?: Maybe;
- description?: Maybe;
- technicalDescription?: Maybe;
- isAvailable?: Maybe;
- count?: Maybe;
- status: ProductStatus;
- priceId?: Maybe;
+export type TrackingTag = {
+ __typename?: 'TrackingTag';
+ id: Scalars['Int'];
+ type: TrackingTagType;
+ value: Scalars['String'];
tenantId: Scalars['Int'];
- stockControl?: Maybe;
- inStockNum?: Maybe;
- price?: Maybe;
- categories?: Maybe>;
- images?: Maybe>;
-};
-
-export type ProductCategoryCreateInput = {
- id?: Maybe;
- title: Scalars['String'];
+ tenant: Tenant;
};
-export type ImageCreateInput = {
- id?: Maybe;
- url: Scalars['String'];
- mime?: Maybe;
- size?: Maybe;
-};
+export enum TrackingTagType {
+ TrackingTagTypeUnspecified = 'TRACKING_TAG_TYPE_UNSPECIFIED',
+ GoogleAnalytics = 'GOOGLE_ANALYTICS',
+ GoogleTagManager = 'GOOGLE_TAG_MANAGER',
+ FacebookPixel = 'FACEBOOK_PIXEL',
+ Hubspot = 'HUBSPOT',
+ Other = 'OTHER',
+}
-export type ProductUpdateInput = {
- title: Scalars['String'];
- slug?: Maybe;
- isOnMainPage: Scalars['Boolean'];
- shortDescription?: Maybe;
- description?: Maybe;
- technicalDescription?: Maybe;
- isAvailable?: Maybe;
+export type Variant = {
+ __typename?: 'Variant';
+ id: Scalars['Int'];
+ name: Scalars['String'];
+ displayName: Scalars['String'];
count?: Maybe;
- status: ProductStatus;
- priceId?: Maybe;
- tenantId: Scalars['Int'];
- stockControl?: Maybe;
- inStockNum?: Maybe;
- price?: Maybe;
- categories?: Maybe>;
- images?: Maybe>;
-};
-
-export type PriceCreateInput = {
- value: Scalars['Int'];
- vatRateId?: Maybe;
-};
-
-export type PriceUpdateInput = {
- value: Scalars['Int'];
- vatRateId?: Maybe;
+ productId?: Maybe;
+ product?: Maybe;
+ attributes?: Maybe>;
};
export type VariantCreateInput = {
name: Scalars['String'];
displayName: Scalars['String'];
count?: Maybe;
- priceId?: Maybe;
productId?: Maybe;
};
@@ -551,31 +649,19 @@ export type VariantUpdateInput = {
name: Scalars['String'];
displayName: Scalars['String'];
count?: Maybe;
- priceId?: Maybe;
productId?: Maybe;
};
-export type AttributeCreateInput = {
- name: Scalars['String'];
- displayName: Scalars['String'];
- value: Scalars['String'];
-};
-
-export type AttributeUpdateInput = {
- name: Scalars['String'];
- displayName: Scalars['String'];
- value: Scalars['String'];
-};
-
-export type AttachmentsListResponse = {
- __typename?: 'AttachmentsListResponse';
- items: Array;
+export type VariantsListResponse = {
+ __typename?: 'VariantsListResponse';
+ items: Array;
};
-export type AttachmentCreateInput = {
- url: Scalars['String'];
- mime: Scalars['String'];
- size: Scalars['Int'];
+export type VatRate = {
+ __typename?: 'VatRate';
+ id: Scalars['Int'];
+ value: Scalars['Int'];
+ tenantId: Scalars['Int'];
};
export type CategoryFragment = { __typename?: 'Category' } & Pick<
@@ -676,14 +762,17 @@ export type ProductShortFragment = { __typename?: 'Product' } & Pick<
| 'count'
| 'stockControl'
| 'inStockNum'
- | 'priceId'
+>;
+
+export type MoneyFragment = { __typename?: 'Money' } & Pick<
+ Money,
+ 'amount' | 'currency' | 'precision'
>;
export type PriceFragment = { __typename?: 'Price' } & {
- formatted: { __typename?: 'FormattedPrice' } & Pick<
- FormattedPrice,
- 'vatAmount' | 'grossAmount' | 'netAmount'
- >;
+ vatAmount: { __typename?: 'Money' } & MoneyFragment;
+ grossAmount: { __typename?: 'Money' } & MoneyFragment;
+ netAmount: { __typename?: 'Money' } & MoneyFragment;
};
export type VariantFragment = { __typename?: 'Variant' } & Pick;
@@ -780,17 +869,28 @@ export const ProductShortFragmentDoc = gql`
count
stockControl
inStockNum
- priceId
+ }
+`;
+export const MoneyFragmentDoc = gql`
+ fragment Money on Money {
+ amount
+ currency
+ precision
}
`;
export const PriceFragmentDoc = gql`
fragment Price on Price {
- formatted {
- vatAmount
- grossAmount
- netAmount
+ vatAmount {
+ ...Money
+ }
+ grossAmount {
+ ...Money
+ }
+ netAmount {
+ ...Money
}
}
+ ${MoneyFragmentDoc}
`;
export const VariantFragmentDoc = gql`
fragment Variant on Variant {
@@ -889,7 +989,8 @@ export function useCreateCategoryMutation(
export type CreateCategoryMutationHookResult = ReturnType<
typeof useCreateCategoryMutation
>;
-export type CreateCategoryMutationResult = Apollo.MutationResult;
+export type CreateCategoryMutationResult =
+ Apollo.MutationResult;
export type CreateCategoryMutationOptions = Apollo.BaseMutationOptions<
CreateCategoryMutation,
CreateCategoryMutationVariables
@@ -942,7 +1043,8 @@ export function useUpdateCategoryMutation(
export type UpdateCategoryMutationHookResult = ReturnType<
typeof useUpdateCategoryMutation
>;
-export type UpdateCategoryMutationResult = Apollo.MutationResult;
+export type UpdateCategoryMutationResult =
+ Apollo.MutationResult;
export type UpdateCategoryMutationOptions = Apollo.BaseMutationOptions<
UpdateCategoryMutation,
UpdateCategoryMutationVariables
@@ -988,7 +1090,8 @@ export function useDeleteCategoryMutation(
export type DeleteCategoryMutationHookResult = ReturnType<
typeof useDeleteCategoryMutation
>;
-export type DeleteCategoryMutationResult = Apollo.MutationResult;
+export type DeleteCategoryMutationResult =
+ Apollo.MutationResult;
export type DeleteCategoryMutationOptions = Apollo.BaseMutationOptions<
DeleteCategoryMutation,
DeleteCategoryMutationVariables
@@ -1329,7 +1432,8 @@ export function useDeleteProductMutation(
export type DeleteProductMutationHookResult = ReturnType<
typeof useDeleteProductMutation
>;
-export type DeleteProductMutationResult = Apollo.MutationResult;
+export type DeleteProductMutationResult =
+ Apollo.MutationResult;
export type DeleteProductMutationOptions = Apollo.BaseMutationOptions<
DeleteProductMutation,
DeleteProductMutationVariables
@@ -1449,7 +1553,8 @@ export function useCreateProductMutation(
export type CreateProductMutationHookResult = ReturnType<
typeof useCreateProductMutation
>;
-export type CreateProductMutationResult = Apollo.MutationResult;
+export type CreateProductMutationResult =
+ Apollo.MutationResult;
export type CreateProductMutationOptions = Apollo.BaseMutationOptions<
CreateProductMutation,
CreateProductMutationVariables
@@ -1503,7 +1608,8 @@ export function useUpdateProductMutation(
export type UpdateProductMutationHookResult = ReturnType<
typeof useUpdateProductMutation
>;
-export type UpdateProductMutationResult = Apollo.MutationResult;
+export type UpdateProductMutationResult =
+ Apollo.MutationResult;
export type UpdateProductMutationOptions = Apollo.BaseMutationOptions<
UpdateProductMutation,
UpdateProductMutationVariables
diff --git a/src/helpers/index.ts b/src/helpers/index.ts
index f002bcc..aa1c396 100644
--- a/src/helpers/index.ts
+++ b/src/helpers/index.ts
@@ -1,12 +1,42 @@
-import numeral from 'numeral';
-import { FormattedPrice } from '../generated/graphql';
+import Dinero, { DineroObject } from 'dinero.js';
+import { Price, Money, CurrencyCode } from '../generated/graphql';
export const formatPrice = (
- formattedPrice?: FormattedPrice | null,
- currency: string | null = 'NOK'
+ price?: Price | null,
+ isVatRequired = false
): string => {
- const amount = numeral(
- formattedPrice ? formattedPrice.netAmount / 100 : 0
- ).format('0.00');
- return currency ? `${amount} ${currency}` : amount;
+ if (!price) return '0';
+
+ const priceValue = (
+ isVatRequired ? price.netAmount : price.grossAmount
+ ) as DineroObject;
+
+ const amount = priceValue ? Dinero(priceValue).toFormat('0.00') : '0';
+ return amount;
+};
+
+export const valueFromString = (
+ value: string,
+ precision = 2,
+ roundRequired = false
+): number => {
+ const nValue = parseFloat(value.replace(',', '.')) * Math.pow(10, precision);
+ if (Number.isNaN(nValue)) return 0;
+ return roundRequired ? Math.round(nValue) : Math.trunc(nValue);
+};
+
+export const moneyFromString = (
+ value: string,
+ precision = 2,
+ currencyCode = CurrencyCode.Nok,
+ roundRequired = false
+): Money => {
+ const nValue = valueFromString(value, precision, roundRequired);
+ const price = {
+ amount: nValue,
+ currency: currencyCode,
+ precision: precision,
+ };
+
+ return price;
};
diff --git a/src/modules/catalog/category/ProductCategories.tsx b/src/modules/catalog/category/ProductCategories.tsx
index 64e210e..57f2b7f 100644
--- a/src/modules/catalog/category/ProductCategories.tsx
+++ b/src/modules/catalog/category/ProductCategories.tsx
@@ -9,13 +9,13 @@ import {
import CategoriesListing from './CategoriesListing';
import { CategoryModalContent } from './CategoryModalContent';
-export type CategoryItem = GetCategoriesWithParentQuery['categories']['items'][0];
+export type CategoryItem =
+ GetCategoriesWithParentQuery['categories']['items'][0];
const Categories: React.FC = () => {
const [openModal, setOpenModal] = useState(false);
- const [currentCategory, setCurrentCategory] = useState(
- null
- );
+ const [currentCategory, setCurrentCategory] =
+ useState(null);
const { data, loading, error } = useGetCategoriesWithParentQuery();
let content = null;
diff --git a/src/modules/catalog/product/ProductCreate.tsx b/src/modules/catalog/product/ProductCreate.tsx
index 86e2364..e664565 100644
--- a/src/modules/catalog/product/ProductCreate.tsx
+++ b/src/modules/catalog/product/ProductCreate.tsx
@@ -7,30 +7,39 @@ import ProductBasicOptions from './components/ProductBasicOptions';
import ProductNavigation from './components/ProductNavigation';
import { TagProps } from '@tabetalt/kit/build/components/InputTags/types';
import {
+ ProductCreateInput,
+ GetProductsDocument,
GetCategoriesShortDocument,
- GetProductDocument,
useCreateProductMutation,
+ ProductCategoryCreateInput,
} from '../../../generated/graphql';
+import * as DineroHelper from '../../../helpers';
const ProductCreate: React.FC = () => {
const navigate = useNavigate();
const [createProduct, { error }] = useCreateProductMutation({
refetchQueries: [
- { query: GetProductDocument },
+ { query: GetProductsDocument },
{ query: GetCategoriesShortDocument },
],
});
const onSubmitBasic = useCallback(
async (values) => {
- const input = {
+ const input: ProductCreateInput = {
tenantId: 1,
...values,
- price: values.price.replace(',', '.') * 100,
+ price: {
+ grossAmount: DineroHelper.moneyFromString(values.price),
+ },
+ stockControl: true,
+ inStockNum: 0,
};
+
if (values.categories) {
+ console.log(values.categories);
input.categories = (values.categories as TagProps[]).map(
- ({ id, name }) => ({ id, title: name })
+ ({ id, name }) => ({ id, title: name } as ProductCategoryCreateInput)
);
}
if (values.images) {
@@ -39,8 +48,8 @@ const ProductCreate: React.FC = () => {
}));
}
- const res = await createProduct({ variables: { input } });
- navigate(`/catalog/product/${res.data?.createProduct?.id}/basic`, {
+ await createProduct({ variables: { input } });
+ navigate(`/catalog/products`, {
replace: true,
});
},
diff --git a/src/modules/catalog/product/ProductUpdate.tsx b/src/modules/catalog/product/ProductUpdate.tsx
index d9c092f..9bcf3b5 100644
--- a/src/modules/catalog/product/ProductUpdate.tsx
+++ b/src/modules/catalog/product/ProductUpdate.tsx
@@ -21,28 +21,31 @@ import {
useUpdateProductMutation,
ProductUpdateInput,
} from '../../../generated/graphql';
+import * as DineroHelper from '../../../helpers';
const ProductUpdate: React.FC = () => {
const navigate = useNavigate();
const params = useParams();
const productId = Number(params.productId);
- const { data, loading, error: errorGetProduct } = useGetProductQuery({
+ const {
+ data,
+ loading,
+ error: errorGetProduct,
+ } = useGetProductQuery({
variables: {
id: productId,
},
});
- const [
- updateProduct,
- { error: errorUpdateProduct },
- ] = useUpdateProductMutation({
- refetchQueries: [
- { query: GetProductsDocument },
- { query: GetProductDocument, variables: { id: productId } },
- { query: GetCategoriesShortDocument },
- ],
- });
+ const [updateProduct, { error: errorUpdateProduct }] =
+ useUpdateProductMutation({
+ refetchQueries: [
+ { query: GetProductsDocument },
+ { query: GetProductDocument, variables: { id: productId } },
+ { query: GetCategoriesShortDocument },
+ ],
+ });
const onSubmit = useCallback(
async (values) => {
@@ -54,7 +57,9 @@ const ProductUpdate: React.FC = () => {
]) as ProductUpdateInput;
if (values.price) {
- input.price = values.price.replace(',', '.') * 100;
+ input.price = {
+ grossAmount: DineroHelper.moneyFromString(values.price),
+ };
}
if (values.categories) {
input.categories = (values.categories as TagProps[]).map(
@@ -67,6 +72,9 @@ const ProductUpdate: React.FC = () => {
}));
}
await updateProduct({ variables: { id: productId, input } });
+ navigate(`/catalog/products`, {
+ replace: true,
+ });
},
[productId, data, updateProduct]
);
diff --git a/src/modules/catalog/product/components/ProductBasicOptions.tsx b/src/modules/catalog/product/components/ProductBasicOptions.tsx
index 412da62..1221881 100644
--- a/src/modules/catalog/product/components/ProductBasicOptions.tsx
+++ b/src/modules/catalog/product/components/ProductBasicOptions.tsx
@@ -13,7 +13,7 @@ import { FormikHelpers, useFormik } from 'formik';
import * as Yup from 'yup';
import { TextPosition } from '@tabetalt/kit/build/components/Input/components/prefilled-input-props';
import { Error } from '../../../../components/common';
-import { formatPrice } from '../../../../helpers';
+import * as DineroHelper from '../../../../helpers';
import { TagProps } from '@tabetalt/kit/build/components/InputTags/types';
import gqlClient from '../../../../api/client';
import {
@@ -83,7 +83,7 @@ const ProductBasicOptions: React.FC = ({
initialValues: {
...defaultValues,
...product,
- price: formatPrice(product?.price?.formatted, null),
+ price: DineroHelper.formatPrice(product?.price),
categories: product?.categories.map((category) => ({
id: category?.id,
name: category?.title,
@@ -150,7 +150,7 @@ const ProductBasicOptions: React.FC = ({
[setFieldValue, form.values.images]
);
- console.log(form.values);
+ //console.log(form.values);
return (