portal-www
Version:
Nova Portal Website. Based on Next starter by Ueno
314 lines (286 loc) • 9.32 kB
text/typescript
import { Cookies } from 'react-cookie';
import { ApolloClient } from '@apollo/client';
import { ADD_MOBILE_TO_CART } from 'graphql/queries/cart/addToCart';
import { MOBILE_CART_QUERY } from 'graphql/queries/cart/getCart';
import { REMOVE_FROM_CART } from 'graphql/queries/cart/removeFromCart';
import { ADD_SHIPPING_METHOD } from 'graphql/queries/cart/shippingMethods';
import { UPDATE_CART_CONTACT, UPDATE_CART_ITEM } from 'graphql/queries/cart/updateCart';
import { identity, pickBy } from 'lodash';
import { action, extendObservable, makeObservable, observable } from 'mobx';
import {
AddMobileSignupToCartMutation,
AddToCartInput,
CartItemInput,
ContactInfoInput,
MobileCartQuery,
RemoveFromCartInput,
RemoveFromCartMutation,
ServiceRequestType,
ShippingMethodInput,
ShippingType,
} from 'typings/graphql';
import Authentication from './authentication';
import { throwErrorWithMessage } from './mobileSignup';
type AddToCartType = 'mobileSignup';
export default class Cart {
private client: ApolloClient<object>;
private authentication: Authentication;
constructor(
{ cart = {} },
client: ApolloClient<object>,
authentication: Authentication,
cookies: string | object | null | undefined,
) {
this.cookies = new Cookies(cookies);
makeObservable(this, {
setActiveCartId: action,
activeCartId: observable,
shipmentOptions: observable,
salesNumber: observable,
customerId: observable,
nationalId: observable,
customerName: observable,
customerAddress: observable,
addToCart: action,
});
extendObservable(this, cart);
this.client = client;
this.authentication = authentication;
}
cookies;
activeCartId: string = '';
salesNumber: string = '';
customerId: string = '';
nationalId: string = '';
customerName: string = '';
customerAddress: string = '';
// ShippingMethods
shipmentOptions: ShippingMethodInput = {
shippingType: ShippingType.Pickup,
id: '',
shippingDetails: {
address: '',
zip: '',
dropp: '',
heimsending: '',
postbox: '',
storename: 'lagmuli',
},
};
setSalesNumber = (salesNumber: string) => {
this.salesNumber = salesNumber;
};
setCustomerId = (customerId: string) => {
this.customerId = customerId;
};
setCustomerName = (name: string) => {
this.customerName = name;
};
setCustomerAddress = (address: string) => {
this.customerAddress = address;
};
setNationalId = (nationalId: string) => {
this.nationalId = nationalId;
};
setShippingMethods = (shipment: ShippingMethodInput) => {
this.shipmentOptions = shipment;
};
setActiveCartId(cartId: string) {
this.activeCartId = cartId;
if (this.authentication.isStaff) {
this.cookies.remove('cartId', { path: '/' });
return;
}
if (!cartId || cartId === '') {
this.cookies.remove('cartId', { path: '/' });
} else {
const expiryDate = new Date();
expiryDate.setHours(expiryDate.getHours() + 12);
this.cookies.set('cartId', cartId, {
path: '/',
expires: expiryDate,
secure: true,
});
}
}
fetchCart = async () => {
if (this.activeCartId) {
try {
const { data } = await this.client.query<MobileCartQuery>({
query: MOBILE_CART_QUERY,
variables: { input: { cartId: this.activeCartId } },
});
return data?.cart;
} catch (error) {
throwErrorWithMessage(error, 'Could not fetch cart');
}
}
};
addToCart = async (type: AddToCartType, item: CartItemInput) => {
try {
const input: AddToCartInput = {
item,
customer: {
ssn: this.nationalId,
},
cartId: this.activeCartId ?? '',
};
let res;
switch (type) {
case 'mobileSignup':
res = await this.client.mutate<AddMobileSignupToCartMutation>({
mutation: ADD_MOBILE_TO_CART,
variables: { input },
});
}
const { data } = res;
if (!this.activeCartId && data?.addToCart.cart?.id) {
this.setActiveCartId(this.activeCartId);
}
return { cart: data };
} catch (e) {
throwErrorWithMessage(e, 'Failed to add to cart');
}
};
removeFromCart = async (cartItemId: string) => {
if (cartItemId) {
try {
const input: RemoveFromCartInput = {
cartId: this.activeCartId,
itemId: cartItemId,
};
const res = await this.client.mutate<RemoveFromCartMutation>({
mutation: REMOVE_FROM_CART,
variables: { input },
});
const { data } = res;
if (data?.removeFromCart?.cart?.id) {
this.activeCartId = data?.removeFromCart.cart.id;
}
} catch (e) {
throwErrorWithMessage(e, 'Failed to add to cart');
}
}
};
updateCartItem = async (item: CartItemInput) => {
if (item?.purchaseInfo) {
item.purchaseInfo = pickBy(item.purchaseInfo, identity);
if (item.purchaseInfo.__typename) {
delete item.purchaseInfo.__typename;
}
if (item.purchaseInfo?.contractExtraPayerInfo) {
item.purchaseInfo.contractExtraPayerInfo = pickBy(
item.purchaseInfo.contractExtraPayerInfo,
identity,
);
if (item.purchaseInfo.contractExtraPayerInfo.__typename) {
delete item.purchaseInfo.contractExtraPayerInfo.__typename;
}
}
if (item?.purchaseInfo?.contract) {
item.purchaseInfo.contract = pickBy(item.purchaseInfo.contract, identity);
if (item.purchaseInfo.contract.__typename) {
delete item.purchaseInfo.contract.__typename;
}
}
if (item?.purchaseInfo?.service) {
if (item.purchaseInfo.service.type !== ServiceRequestType.Mobile) {
item.purchaseInfo.service = pickBy(item.purchaseInfo.service, identity);
}
if (item.purchaseInfo.service.__typename) {
delete item.purchaseInfo.service.__typename;
}
}
if (item?.purchaseInfo?.service?.user) {
item.purchaseInfo.service.user = pickBy(item.purchaseInfo.service.user, identity);
if (item.purchaseInfo.service.user?.__typename) {
delete item.purchaseInfo.service.user.__typename;
}
}
if (item?.purchaseInfo?.service?.mobileSignupRightHolder) {
item.purchaseInfo.service.mobileSignupRightHolder = pickBy(
item.purchaseInfo.service.mobileSignupRightHolder,
identity,
);
if (item.purchaseInfo.service.mobileSignupRightHolder?.__typename) {
delete item.purchaseInfo.service.mobileSignupRightHolder.__typename;
}
}
if (item?.purchaseInfo?.service?.appointment) {
item.purchaseInfo.service.appointment = pickBy(
item.purchaseInfo.service.appointment,
identity,
);
if (item?.purchaseInfo?.service?.appointment?.__typename) {
delete item.purchaseInfo.service.appointment.__typename;
}
}
if (item?.purchaseInfo?.service?.refillInfo) {
item.purchaseInfo.service.refillInfo = pickBy(item.purchaseInfo.rental, identity);
if (item?.purchaseInfo?.service?.refillInfo?.__typename) {
delete item.purchaseInfo.service?.refillInfo?.__typename;
}
}
if (item?.purchaseInfo?.rental) {
item.purchaseInfo.rental = pickBy(item.purchaseInfo.rental, identity);
if (item?.purchaseInfo?.rental?.__typename) {
delete item.purchaseInfo.rental.__typename;
}
}
}
try {
const res = await this.client.mutate({
mutation: UPDATE_CART_ITEM,
variables: { input: { cartId: this.activeCartId, item } },
update: (_, { data }) => {
this.client.writeQuery({
query: UPDATE_CART_ITEM,
variables: { input: { cartId: this.activeCartId } },
data,
});
},
});
const {
data: {
updateCartItem: { cart },
},
} = res;
this.activeCartId = cart.id;
} catch (e) {
throwErrorWithMessage(e, 'Failed to update cart');
}
};
updateCartContact = async (contactInfo: ContactInfoInput) => {
try {
await this.client.mutate({
mutation: UPDATE_CART_CONTACT,
variables: { input: { cartId: this.activeCartId, contactInfo: contactInfo } },
update: (_, { data }) => {
this.client.writeQuery({
query: UPDATE_CART_CONTACT,
variables: { input: { cartId: this.activeCartId, contactInfo: contactInfo } },
data,
});
},
});
} catch (e) {
throwErrorWithMessage(e, 'Failed to update cart contact');
}
};
addShippingMethod = async () => {
try {
const res = await this.client.mutate({
mutation: ADD_SHIPPING_METHOD,
variables: { input: { cartId: this.activeCartId, shippingMethod: this.shipmentOptions } },
});
const {
data: {
addShippingMethod: { cart },
},
} = res;
this.activeCartId = cart.id;
} catch (e) {
throwErrorWithMessage(e, 'Failed to update cart contact');
}
};
}