Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@
},
"dependencies": {
"@commercetools/platform-sdk": "^7.8.0",
"@commercetools/sdk-auth": "^4.0.1",
"@commercetools/sdk-client-v2": "^2.5.0",
"@commercetools/sdk-middleware-auth": "^7.0.1",
"@types/node-fetch": "^2.6.11",
"dotenv": "^16.4.5",
"isomorphic-fetch": "^3.0.0",
Expand Down
1 change: 0 additions & 1 deletion src/app/models/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ interface ILocalizedString {
}

export interface ICurrent {
id: string;
name: ILocalizedString;
description?: ILocalizedString;
masterVariant: {
Expand Down
46 changes: 46 additions & 0 deletions src/app/services/add-product-cart.ts
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean code, nice work!

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { ClientResponse, Cart } from '@commercetools/platform-sdk';
import apiRoot from './api-root';

// Отправляет запрос на добавление товара в корзину
// При успешном добавлении товара вызывает successCallback с обновленными данными корзины
// eslint-disable-next-line import/prefer-default-export
export const addProductToCart = (
cartId: string,
cartVersion: number,
productId: string,
quantity: number,
successCallback: (cartData: Cart) => void,
errorCallback: (message: string) => void
): void => {
console.log('addProductToCart called with:', {
cartId,
cartVersion,
productId,
quantity,
});
apiRoot
.carts()
.withId({ ID: cartId })
.post({
body: {
version: cartVersion,
actions: [
{
action: 'addLineItem',
productId,
quantity,
},
],
},
})
.execute()
.then((response: ClientResponse<Cart>) => {
const cartData: Cart = response.body;
console.log('Product added to cart successfully:', cartData);
successCallback(cartData);
})
.catch((error: ClientResponse<{ message: string }>) => {
console.error('Error adding product to cart:', error.body);
errorCallback(error.body.message);
});
};
66 changes: 66 additions & 0 deletions src/app/services/auth-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import fetch from 'isomorphic-fetch';
// eslint-disable-next-line import/no-extraneous-dependencies
import SdkAuth from '@commercetools/sdk-auth';
import { getCustomerToken } from '@models/customer';
import { clientConfig } from './client';

const AUTH_TOKEN_KEY = 'authToken';

interface IUserCredentials {
username: string;
password: string;
}

const sdkAuth = new SdkAuth({
host: clientConfig.VITE_CTP_AUTH_URL,
projectKey: clientConfig.VITE_CTP_PROJECT_KEY,
credentials: {
clientId: clientConfig.VITE_CTP_CLIENT_ID,
clientSecret: clientConfig.VITE_CTP_CLIENT_SECRET,
},
fetch,
});

export async function getUserToken(
credentials: IUserCredentials
): Promise<string> {
const tokenResponse = await sdkAuth.customerPasswordFlow({
username: credentials.username,
password: credentials.password,
});

if (!tokenResponse.access_token) {
throw new Error('Failed to fetch token');
}

return tokenResponse.access_token;
}

// Функция для получения токена и сохранения его в локальное хранилище
export async function fetchAndStoreUserToken(): Promise<void> {
const customerData = getCustomerToken();
console.log('Customer data from localStorage:', customerData);
if (!customerData) {
throw new Error('No customer data found in localStorage.');
}

if (!customerData.email || !customerData.password) {
throw new Error('Customer data is missing required fields.');
}

const credentials: IUserCredentials = {
username: customerData.email,
password: customerData.password,
};

console.log('Credentials for token request:', credentials);

try {
const token = await getUserToken(credentials);
localStorage.setItem(AUTH_TOKEN_KEY, token);
console.log('Token saved to localStorage:', token);
} catch (error) {
console.error('Error fetching user token:', error);
throw new Error('Failed to fetch user token.');
}
}
118 changes: 118 additions & 0 deletions src/app/services/cart-handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { addProductToCart } from './add-product-cart';
import { createAnonymousCart, createCustomerCart } from './carts';

class CartHandler {
private currentCartId: string | null = null;

private currentCartVersion: number | null = null;

private userId: string | null = null;

constructor(userId: string | null) {
this.userId = userId;
if (!userId) {
this.loadCartFromLocalStorage();
} else {
this.loadCartFromServer(userId);
}
}

public handleAddToCart(productId: string, quantity: number): void {
if (!this.currentCartId || !this.currentCartVersion) {
this.createCartAndAddProduct(productId, quantity);
} else {
this.addProductToExistingCart(
this.currentCartId,
this.currentCartVersion,
productId,
quantity
);
}
}

private createCartAndAddProduct(productId: string, quantity: number): void {
if (this.userId) {
createCustomerCart(
this.userId,
(cartData) => {
this.currentCartId = cartData.id;
this.currentCartVersion = cartData.version;
this.addProductToExistingCart(
this.currentCartId,
this.currentCartVersion,
productId,
quantity
);
},
(errorMessage) => {
console.error('Error creating user cart:', errorMessage);
}
);
} else {
createAnonymousCart(
(cartData) => {
this.currentCartId = cartData.id;
this.currentCartVersion = cartData.version;
this.saveCartToLocalStorage();
this.addProductToExistingCart(
this.currentCartId,
this.currentCartVersion,
productId,
quantity
);
},
(errorMessage) => {
console.error('Error creating anonymous cart:', errorMessage);
}
);
}
}

private addProductToExistingCart(
cartId: string,
cartVersion: number,
productId: string,
quantity: number
): void {
addProductToCart(
cartId,
cartVersion,
productId,
quantity,
(cartData) => {
this.currentCartId = cartData.id;
this.currentCartVersion = cartData.version;
if (!this.userId) {
this.saveCartToLocalStorage();
}
console.log('Product added to cart:', cartData);
},
(errorMessage) => {
console.error('Error adding product to cart:', errorMessage);
}
);
}

private saveCartToLocalStorage(): void {
const cartData = {
currentCartId: this.currentCartId,
currentCartVersion: this.currentCartVersion,
};
localStorage.setItem('anonymousCart', JSON.stringify(cartData));
}

private loadCartFromLocalStorage(): void {
const savedCart = localStorage.getItem('anonymousCart');
if (savedCart) {
const cartData = JSON.parse(savedCart);
this.currentCartId = cartData.currentCartId;
this.currentCartVersion = cartData.currentCartVersion;
}
}

// метод для загрузки корзины зарегистрированного пользователя с сервера
// eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars
private loadCartFromServer(userId: string): void {}
}

export default CartHandler;
49 changes: 49 additions & 0 deletions src/app/services/carts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Cart, ClientResponse } from '@commercetools/platform-sdk';
import apiRoot from './api-root';

// запрос на создание анон cart
// При успешном создании корзины вызывает successCallback с данными корзины.
export const createAnonymousCart = (
successCallback: (cartData: Cart) => void,
errorCallback: (message: string) => void
): void => {
apiRoot
.carts()
.post({
body: {
currency: 'USD',
},
})
.execute()
.then((response: ClientResponse<Cart>) => {
const cartData: Cart = response.body;
console.log(cartData);
successCallback(cartData);
})
.catch((error: ClientResponse<{ message: string }>) => {
errorCallback(error.body.message);
});
};

export const createCustomerCart = (
customerId: string,
successCallback: (cartData: Cart) => void,
errorCallback: (message: string) => void
): void => {
apiRoot
.carts()
.post({
body: {
currency: 'USD',
customerId,
},
})
.execute()
.then((response: ClientResponse<Cart>) => {
const cartData: Cart = response.body;
successCallback(cartData);
})
.catch((error: ClientResponse<{ message: string }>) => {
errorCallback(error.body.message);
});
};
Loading