diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/utils/address.js | 27 | ||||
| -rw-r--r-- | src/core/utils/apiOdoo.js | 44 | ||||
| -rw-r--r-- | src/core/utils/auth.js | 38 | ||||
| -rw-r--r-- | src/core/utils/cart.js | 36 | ||||
| -rw-r--r-- | src/core/utils/convertToOption.js | 11 | ||||
| -rw-r--r-- | src/core/utils/currencyFormat.js | 8 | ||||
| -rw-r--r-- | src/core/utils/formValidation.js | 107 | ||||
| -rw-r--r-- | src/core/utils/getFileBase64.js | 11 | ||||
| -rw-r--r-- | src/core/utils/greeting.js | 9 | ||||
| -rw-r--r-- | src/core/utils/mailer.js | 12 | ||||
| -rw-r--r-- | src/core/utils/slug.js | 25 | ||||
| -rw-r--r-- | src/core/utils/toTitleCase.js | 8 |
12 files changed, 336 insertions, 0 deletions
diff --git a/src/core/utils/address.js b/src/core/utils/address.js new file mode 100644 index 00000000..c4a19af5 --- /dev/null +++ b/src/core/utils/address.js @@ -0,0 +1,27 @@ +const getAddress = () => { + const address = localStorage.getItem('address'); + if (address) return JSON.parse(address); + return {}; +} + +const setAddress = (address) => { + localStorage.setItem('address', JSON.stringify(address)); + return true; +} + +const getItemAddress = (key) => { + let address = getAddress(); + return address[key]; +} + +const createOrUpdateItemAddress = (key, value) => { + let address = getAddress(); + address[key] = value; + setAddress(address); + return true; +} + +export { + getItemAddress, + createOrUpdateItemAddress +};
\ No newline at end of file diff --git a/src/core/utils/apiOdoo.js b/src/core/utils/apiOdoo.js new file mode 100644 index 00000000..4d0adae3 --- /dev/null +++ b/src/core/utils/apiOdoo.js @@ -0,0 +1,44 @@ +import { getCookie, setCookie } from 'cookies-next'; +import axios from 'axios'; +import { getAuth } from './auth'; + +const renewToken = async () => { + let token = await axios.get(process.env.SELF_HOST + '/api/token'); + setCookie('token', token.data); + return token.data; +}; + +const getToken = async () => { + let token = getCookie('token'); + if (token == undefined) token = await renewToken(); + return token; +}; + +let connectionTry = 0; +const apiOdoo = async (method, url, data = {}, headers = {}) => { + try { + connectionTry++; + let token = await getToken(); + let axiosParameter = { + method, + url: process.env.ODOO_HOST + url, + headers: {'Authorization': token, ...headers} + } + const auth = getAuth(); + + if (auth) axiosParameter.headers['Token'] = auth.token; + if (method.toUpperCase() == 'POST') axiosParameter.headers['Content-Type'] = 'application/x-www-form-urlencoded'; + if (Object.keys(data).length > 0) axiosParameter.data = new URLSearchParams(Object.entries(data)).toString(); + + let res = await axios(axiosParameter); + if (res.data.status.code == 401 && connectionTry < 15) { + await renewToken(); + return apiOdoo(method, url, data, headers); + } + return res.data.result || []; + } catch (error) { + console.log(error) + } +} + +export default apiOdoo;
\ No newline at end of file diff --git a/src/core/utils/auth.js b/src/core/utils/auth.js new file mode 100644 index 00000000..62eba2c0 --- /dev/null +++ b/src/core/utils/auth.js @@ -0,0 +1,38 @@ +import { deleteCookie, getCookie, setCookie } from 'cookies-next'; +import { useEffect, useState } from 'react'; + +const getAuth = () => { + let auth = getCookie('auth'); + if (auth) { + return JSON.parse(auth); + } + return false; +} + +const setAuth = (user) => { + setCookie('auth', JSON.stringify(user)); + return true; +} + +const deleteAuth = () => { + deleteCookie('auth'); + return true; +} + +const useAuth = () => { + const [auth, setAuth] = useState(null); + + useEffect(() => { + const handleIsAuthenticated = () => setAuth(getAuth()); + handleIsAuthenticated(); + }, []); + + return [auth, setAuth]; +} + +export { + getAuth, + setAuth, + deleteAuth, + useAuth +};
\ No newline at end of file diff --git a/src/core/utils/cart.js b/src/core/utils/cart.js new file mode 100644 index 00000000..66efcbf2 --- /dev/null +++ b/src/core/utils/cart.js @@ -0,0 +1,36 @@ +const getCart = () => { + const cart = localStorage.getItem('cart'); + if (cart) return JSON.parse(cart); + return {}; +} + +const setCart = (cart) => { + localStorage.setItem('cart', JSON.stringify(cart)); + return true; +} + +const getItemCart = (product_id) => { + let cart = getCart(); + return cart[product_id]; +} + +const createOrUpdateItemCart = (product_id, quantity, selected = false) => { + let cart = getCart(); + cart[product_id] = { product_id, quantity, selected }; + setCart(cart); + return true; +} + +const deleteItemCart = (product_id) => { + let cart = getCart(); + delete cart[product_id]; + setCart(cart); + return true; +} + +export { + getCart, + getItemCart, + createOrUpdateItemCart, + deleteItemCart +}
\ No newline at end of file diff --git a/src/core/utils/convertToOption.js b/src/core/utils/convertToOption.js new file mode 100644 index 00000000..08fec08f --- /dev/null +++ b/src/core/utils/convertToOption.js @@ -0,0 +1,11 @@ +const convertToOption = (data) => { + if (data) { + return { + value: data.id, + label: data.name, + } + } + return null; +}; + +export default convertToOption;
\ No newline at end of file diff --git a/src/core/utils/currencyFormat.js b/src/core/utils/currencyFormat.js new file mode 100644 index 00000000..dadeaec6 --- /dev/null +++ b/src/core/utils/currencyFormat.js @@ -0,0 +1,8 @@ +export default function currencyFormat(value) { + const currency = new Intl.NumberFormat('id-ID', { + style: 'currency', + currency: 'IDR', + maximumFractionDigits: 0 + }); + return currency.format(value); +}
\ No newline at end of file diff --git a/src/core/utils/formValidation.js b/src/core/utils/formValidation.js new file mode 100644 index 00000000..0e83f4cc --- /dev/null +++ b/src/core/utils/formValidation.js @@ -0,0 +1,107 @@ +import { useCallback, useEffect, useState } from "react"; + +const validateForm = (data, queries, hasChangedInputs = null) => { + let result = { valid: true, errors: {} }; + + for (const query in queries) { + if (!hasChangedInputs || (hasChangedInputs && hasChangedInputs[query])) { + const value = data[query]; + const rules = queries[query]; + let errors = []; + let label = null; + for (const rule of rules) { + let emailValidationRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + if (rule.startsWith('label:')) { + label = rule.replace('label:', ''); + } else if (rule === 'required' && !value) { + errors.push('tidak boleh kosong'); + } else if (rule === 'email' && !value.match(emailValidationRegex)) { + errors.push('harus format johndoe@example.com'); + } else if (rule.startsWith('maxLength:')) { + let maxLength = parseInt(rule.replace('maxLength:', '')); + if (value && value.length > maxLength) errors.push(`maksimal ${maxLength} karakter`); + } + } + if (errors.length > 0) { + result.errors[query] = (label || query) + ' ' + errors.join(', '); + } + } + } + + if (Object.keys(result.errors).length > 0) { + result.valid = false; + } + + return result; +} + +const useFormValidation = ({ initialFormValue = {}, validationScheme = {} }) => { + const [ formInputs, setFormInputs ] = useState(initialFormValue); + const [ formErrors, setFormErrors ] = useState({}); + const [ formValidation ] = useState(validationScheme); + const [ hasChangedInputs, setHasChangedInputs ] = useState({}); + + const handleFormSubmit = (event, func) => { + if (event) { + event.preventDefault(); + + // Make all input to be has changed mode to revalidate + const changedInputs = {}; + for (const key in formInputs) changedInputs[key] = true; + setHasChangedInputs(changedInputs); + + const { valid, errors } = validateForm(formInputs, formValidation, changedInputs); + setFormErrors(errors); + + if (valid) func(); + } + }; + + const setChangedInput = (name, value = true) => { + setHasChangedInputs((hasChangedInputs) => ({ + ...hasChangedInputs, + [name]: value + })); + }; + + const handleInputChange = (event) => { + setFormInputs((formInputs) => ({ + ...formInputs, + [event.target.name]: event.target.value + })); + setChangedInput(event.target.name); + }; + + const handleSelectChange = useCallback((name, value) => { + setFormInputs((formInputs) => ({ + ...formInputs, + [name]: value + })); + setChangedInput(name); + }, []); + + const handleFormReset = () => { + setFormInputs(initialFormValue); + setFormErrors({}); + setHasChangedInputs({}); + } + + useEffect(() => { + if (formInputs) { + const { errors } = validateForm(formInputs, formValidation, hasChangedInputs); + setFormErrors(errors); + } + }, [ formInputs, formValidation, hasChangedInputs ]) + + return { + handleFormReset, + handleFormSubmit, + handleInputChange, + handleSelectChange, + hasChangedInputs, + formInputs, + formErrors + }; + }; + +export default useFormValidation;
\ No newline at end of file diff --git a/src/core/utils/getFileBase64.js b/src/core/utils/getFileBase64.js new file mode 100644 index 00000000..78013e43 --- /dev/null +++ b/src/core/utils/getFileBase64.js @@ -0,0 +1,11 @@ +const getFileBase64 = file => new Promise((resolve, reject) => { + let reader = new FileReader(); + reader.readAsBinaryString(file); + reader.onload = () => { + let result = reader.result; + resolve(btoa(result)); + }; + reader.onerror = error => reject(error); +}); + +export default getFileBase64;
\ No newline at end of file diff --git a/src/core/utils/greeting.js b/src/core/utils/greeting.js new file mode 100644 index 00000000..7dc19f8f --- /dev/null +++ b/src/core/utils/greeting.js @@ -0,0 +1,9 @@ +const greeting = () => { + let hours = new Date().getHours(); + if (hours < 11) return 'Selamat Pagi'; + if (hours < 15) return 'Selamat Siang'; + if (hours < 18) return 'Selamat Sore'; + return 'Selamat Malam'; +} + +export default greeting;
\ No newline at end of file diff --git a/src/core/utils/mailer.js b/src/core/utils/mailer.js new file mode 100644 index 00000000..4e7ff7cc --- /dev/null +++ b/src/core/utils/mailer.js @@ -0,0 +1,12 @@ +const nodemailer = require('nodemailer'); +const mailer = nodemailer.createTransport({ + port: process.env.MAIL_PORT, + host: process.env.MAIL_HOST, + auth: { + user: process.env.MAIL_USER, + pass: process.env.MAIL_PASS + }, + secure: true +}); + +export default mailer;
\ No newline at end of file diff --git a/src/core/utils/slug.js b/src/core/utils/slug.js new file mode 100644 index 00000000..0a7d30fc --- /dev/null +++ b/src/core/utils/slug.js @@ -0,0 +1,25 @@ +import toTitleCase from './toTitleCase'; + +const createSlug = (name, id) => { + let slug = name?.trim().replace(new RegExp(/[^A-Za-z0-9]/, 'g'), '-').toLowerCase() + '-' + id; + let splitSlug = slug.split('-'); + let filterSlugFromEmptyChar = splitSlug.filter(x => x != ''); + return filterSlugFromEmptyChar.join('-'); +} + +const getIdFromSlug = (slug) => { + let id = slug.split('-'); + return id[id.length-1]; +} + +const getNameFromSlug = (slug) => { + let name = slug.split('-'); + name.pop(); + return toTitleCase(name.join(' ')); +} + +export { + createSlug, + getIdFromSlug, + getNameFromSlug +};
\ No newline at end of file diff --git a/src/core/utils/toTitleCase.js b/src/core/utils/toTitleCase.js new file mode 100644 index 00000000..5cfd70d0 --- /dev/null +++ b/src/core/utils/toTitleCase.js @@ -0,0 +1,8 @@ +export default function toTitleCase(str) { + return str.replace( + /\w\S*/g, + function(txt) { + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + } + ); +}
\ No newline at end of file |
