Move functions to directory
This commit is contained in:
120
src/utils/functions/index.ts
Normal file
120
src/utils/functions/index.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Throttle function
|
||||
*/
|
||||
export const throttle = (func: Function, timeout: number) => {
|
||||
let ready: boolean = true
|
||||
return (...args: any) => {
|
||||
if (!ready) return
|
||||
ready = false
|
||||
func(...args)
|
||||
setTimeout(() => ready = true, timeout)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Debounce function
|
||||
*/
|
||||
export const debounce = (func: Function, timeout: number) => {
|
||||
let timer: NodeJS.Timeout
|
||||
return (...args: any) => {
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(() => func(...args), timeout)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Split text
|
||||
* @description Split a string into words or characters
|
||||
* @returns string[]
|
||||
*/
|
||||
export const splitText = (text: string, mode: string = 'words'): string[] => {
|
||||
// Split by words
|
||||
if (mode === 'words') {
|
||||
const words = text
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\s+/g, m => m.includes('\n') ? '\n ' : ' ')
|
||||
.trim()
|
||||
.split(' ')
|
||||
|
||||
return words
|
||||
}
|
||||
// Split by chars
|
||||
else if (mode === 'chars') {
|
||||
const chars = Array.from(text).map(char => char === ' ' ? '\xa0' : char)
|
||||
return chars
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Capitalize first letter
|
||||
*/
|
||||
export const capitalizeFirstLetter = (string: string) => {
|
||||
return string[0].toUpperCase() + string.slice(1)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Linear Interpolation
|
||||
*/
|
||||
export const lerp = (start: number, end: number, amt: number): number => {
|
||||
return (1 - amt) * start + amt * end
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Re-maps a number from one range to another
|
||||
* @param value the incoming value to be converted
|
||||
* @param start1 lower bound of the value's current range
|
||||
* @param stop1 upper bound of the value's current range
|
||||
* @param start2 lower bound of the value's target range
|
||||
* @param stop2 upper bound of the value's target range
|
||||
* @param [withinBounds] constrain the value to the newly mapped range
|
||||
* @return remapped number
|
||||
*/
|
||||
export const map = (n: number, start1: number, stop1: number, start2: number, stop2: number, withinBounds: boolean): number => {
|
||||
const value = (n - start1) / (stop1 - start1) * (stop2 - start2) + start2
|
||||
if (!withinBounds) return value
|
||||
if (start2 < stop2) {
|
||||
return clamp(value, start2, stop2)
|
||||
} else {
|
||||
return clamp(value, stop2, start2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clamp a number
|
||||
*/
|
||||
export const clamp = (num: number, a: number, b: number) => {
|
||||
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a random element from an array
|
||||
*/
|
||||
export const getRandomElement = (array: any[]): any => {
|
||||
return ~~(array.length * Math.random())
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a DOM element's position
|
||||
*/
|
||||
export const getPosition = (node, scope?: HTMLElement) => {
|
||||
const root = scope || document
|
||||
let offsetTop = node.offsetTop
|
||||
let offsetLeft = node.offsetLeft
|
||||
while (node && node.offsetParent && node.offsetParent != document && node !== root && root !== node.offsetParent) {
|
||||
offsetTop += node.offsetParent.offsetTop
|
||||
offsetLeft += node.offsetParent.offsetLeft
|
||||
node = node.offsetParent
|
||||
}
|
||||
return {
|
||||
top: offsetTop,
|
||||
left: offsetLeft
|
||||
}
|
||||
}
|
||||
40
src/utils/functions/notifications.ts
Normal file
40
src/utils/functions/notifications.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { cartNotifications } from '$utils/stores/shop'
|
||||
|
||||
interface Notification {
|
||||
title: string
|
||||
name: string
|
||||
image: string
|
||||
timeout?: number
|
||||
id?: number
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a notification
|
||||
*/
|
||||
export const addNotification = (notification: Notification) => {
|
||||
const id = Math.floor(Math.random() * 10000)
|
||||
|
||||
// Add ID and default timeout
|
||||
notification = {
|
||||
id,
|
||||
timeout: notification.timeout || 3000,
|
||||
...notification,
|
||||
}
|
||||
|
||||
// Push the notifications to the top of the list of notificationss
|
||||
cartNotifications.update((all) => [notification, ...all])
|
||||
|
||||
// If notification is dismissible, dismiss it after an amount of time (timeout)
|
||||
if (notification.timeout) {
|
||||
setTimeout(() => dismissNotification(id), notification.timeout)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dismiss a notification
|
||||
*/
|
||||
export const dismissNotification = (id: number) => {
|
||||
cartNotifications.update((all) => all.filter((t) => t.id !== id))
|
||||
}
|
||||
33
src/utils/functions/shop.ts
Normal file
33
src/utils/functions/shop.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { addNotification } from '$utils/functions/notifications'
|
||||
import type { Writable } from 'svelte/store'
|
||||
|
||||
|
||||
/**
|
||||
* Add a product to a cart
|
||||
*/
|
||||
export const addToCart = async (cart: string, cartData: Writable<any>, product: any, quantity: number = 1) => {
|
||||
if (cart && cart !== 'null') {
|
||||
const updatedCart = await fetch('/api/swell', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
action: 'addToCart',
|
||||
cartId: cart,
|
||||
productId: product.id,
|
||||
quantity,
|
||||
})
|
||||
})
|
||||
if (updatedCart.ok) {
|
||||
const newCart = await updatedCart.json()
|
||||
cartData.set(newCart)
|
||||
|
||||
// Show notification
|
||||
addNotification({
|
||||
title: 'Added to cart',
|
||||
name: `${product.name} - x1`,
|
||||
image: product.images[0].file.url,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.log('No active cart')
|
||||
}
|
||||
}
|
||||
137
src/utils/functions/swell.ts
Normal file
137
src/utils/functions/swell.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
import swell from 'swell-node'
|
||||
|
||||
// Init Swell
|
||||
swell.init(import.meta.env.VITE_SWELL_STORE_ID, import.meta.env.VITE_SWELL_API_TOKEN)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a product
|
||||
*/
|
||||
export const getProduct = async (id: string) => {
|
||||
const product = await swell.get('/products/{id}', {
|
||||
id
|
||||
})
|
||||
|
||||
if (product) {
|
||||
return product
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a cart
|
||||
*/
|
||||
export const createCart = async () => {
|
||||
const cart = await swell.post('/carts')
|
||||
|
||||
if (cart) {
|
||||
return cart
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve cart
|
||||
*/
|
||||
export const fetchCart = async (id: string) => {
|
||||
const cart = await swell.get('/carts/{id}', {
|
||||
id,
|
||||
expand: [
|
||||
'items.product',
|
||||
'items.variant',
|
||||
]
|
||||
})
|
||||
|
||||
if (cart) {
|
||||
return cart
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add product to cart
|
||||
*/
|
||||
export const addToCart = async (cartId: string, productId: string, quantity: number) => {
|
||||
// Fetch current cart data
|
||||
const currentCart = await fetchCart(cartId)
|
||||
|
||||
// Updated cart with new items
|
||||
const updatedCart = await swell.put('/carts/{id}', {
|
||||
id: cartId,
|
||||
items: [
|
||||
...currentCart.items || [],
|
||||
{
|
||||
product_id: productId,
|
||||
quantity,
|
||||
}
|
||||
],
|
||||
})
|
||||
if (updatedCart) {
|
||||
// Fetch latest cart with updates
|
||||
const cart = await fetchCart(cartId)
|
||||
if (cart) {
|
||||
return cart
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update cart item
|
||||
*/
|
||||
export const updateCartItem = async (cartId: string, productId: string, quantity: number) => {
|
||||
// Fetch current cart data
|
||||
const currentCart = await fetchCart(cartId)
|
||||
|
||||
// Updated items with replacing new item quantity
|
||||
const updatedCartItems = currentCart.items.map((item: any) => {
|
||||
// Replace item quantity with selected one
|
||||
if (item.id === productId) {
|
||||
item.quantity = quantity
|
||||
}
|
||||
return item
|
||||
})
|
||||
|
||||
const updatedCart = await swell.put('/carts/{id}', {
|
||||
id: cartId,
|
||||
$set: {
|
||||
items: updatedCartItems,
|
||||
}
|
||||
})
|
||||
if (updatedCart) {
|
||||
// Fetch latest cart with updates
|
||||
const cart = await fetchCart(cartId)
|
||||
if (cart) {
|
||||
return cart
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove cart item
|
||||
*/
|
||||
export const removeCartItem = async (cartId: string, productId: string) => {
|
||||
// Fetch current cart data
|
||||
const currentCart = await fetchCart(cartId)
|
||||
|
||||
// Updated items and remove selected item
|
||||
const updatedCartItems = [...currentCart.items.filter((item: any) => {
|
||||
return item.id !== productId
|
||||
})]
|
||||
|
||||
const updatedCart = await swell.put('/carts/{id}', {
|
||||
id: cartId,
|
||||
$set: {
|
||||
items: updatedCartItems,
|
||||
}
|
||||
})
|
||||
if (updatedCart) {
|
||||
// Fetch latest cart with updates
|
||||
const cart = await fetchCart(cartId)
|
||||
if (cart) {
|
||||
return cart
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user