4 | {{ $props.description }}
6 |Currency preview
27 |Date preview
31 || Unit | 11 |Default | 12 |13 | | 14 | |
|---|---|---|---|
| 19 | 20 | | 21 |22 | 29 | | 30 |31 | | 32 | 35 | | 36 |
| Title | 10 |Value | 11 |12 | | 13 | |
|---|---|---|---|
|
18 |
19 |
20 |
21 | |
22 |
23 |
24 |
36 |
42 |
43 | |
44 | 45 | | 46 | 49 | | 50 |
| Token | 46 |Created at | 47 |48 | |
|---|---|---|
| 53 | {{ t.name }} 54 | | 55 |56 | {{ useFormat.date(t.createdAt) }} 57 | | 58 |59 | 62 | | 63 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa.
", 56 | quantity: 5, 57 | price: 300, 58 | tax: 20, 59 | unit: "hrs", 60 | }, 61 | { 62 | id: Date.now(), 63 | taxPrice: 0, 64 | discount: 0, 65 | net: 0, 66 | netNoDiscount: 0, 67 | total: 0, 68 | totalPercentage: 0, 69 | focused: false, 70 | title: "Lorem ipsum dolor sit amet", 71 | text: "Lorem ipsum dolor sit amet, consectetuer
", 72 | quantity: 10, 73 | price: 10000, 74 | tax: 20, 75 | unit: "hrs", 76 | }, 77 | ]; 78 | document.data.taxOption = { 79 | title: "Apply taxes", 80 | applicable: true, 81 | default: true, 82 | }; 83 | document.data.discountsCharges = [ 84 | { 85 | title: "Some discount", 86 | value: 5, 87 | type: DCType.Discount, 88 | valueType: ValueType.Percent, 89 | amount: 10, 90 | }, 91 | ]; 92 | 93 | document.calculate(); 94 | 95 | return document; 96 | } 97 | } 98 | 99 | export { Example }; 100 | -------------------------------------------------------------------------------- /apps/frontend/composables/useHttp.ts: -------------------------------------------------------------------------------- 1 | import camelcaseKeys from "camelcase-keys"; 2 | 3 | type FetchMethod = "get" | "post" | "put" | "delete" | "patch" | "head" | "options"; 4 | export default class HttpClient { 5 | public static get = async (url: string, notify: boolean | { title: string; text: string; type?: string } = false) => 6 | await this.doFetch(url, { method: "get" }, notify); 7 | public static del = async (url: string, notify: boolean | { title: string; text: string; type?: string } = false) => 8 | await this.doFetch(url, { method: "delete" }, notify); 9 | public static post = async (url: string, data: any, notify: boolean | { title: string; text: string; type?: string } = false) => 10 | await this.doFetch(url, { method: "post", body: data }, notify); 11 | public static put = async (url: string, data: any, notify: boolean | { title: string; text: string; type?: string } = false) => 12 | await this.doFetch(url, { method: "put", body: data }, notify); 13 | 14 | public static doFetch = async ( 15 | url: string, 16 | opts: { method: FetchMethod; body?: any }, 17 | notify: boolean | { title: string; text: string; type?: string } = false, 18 | ) => { 19 | await useInfo().init(); 20 | if (useInfo().info === null) { 21 | return {}; 22 | } 23 | const baseUrl = useInfo().info.BASE_URL; 24 | 25 | const origin = useRequestURL().origin; 26 | try { 27 | const headers: any = { 28 | "content-type": "application/json", 29 | origin: origin, 30 | }; 31 | if (useAuth().key() !== null) { 32 | headers["Authorization"] = `Bearer ${useAuth().key()}`; 33 | } 34 | 35 | const res = await $fetch.raw(`${baseUrl}${url}`, { 36 | method: opts.method, 37 | body: JSON.stringify(opts.body), 38 | headers: headers, 39 | }); 40 | 41 | if (typeof notify !== "boolean") { 42 | useToast(notify.title, notify.text, notify.type || "success"); 43 | } 44 | 45 | if (res.status >= 400 && notify) { 46 | useToast("Error", JSON.stringify(res._data) || "Unexpected error", "error"); 47 | } 48 | 49 | return { body: camelcaseKeys(res._data as any, { deep: true }), headers: res.headers }; 50 | } catch (e) { 51 | if (notify) { 52 | this.notifyError(e); 53 | } 54 | 55 | return {}; 56 | } 57 | }; 58 | 59 | private static notifyError(e: any) { 60 | let title = "Error"; 61 | let message = "Unexpected error occured"; 62 | 63 | if (e.data) { 64 | if (e.data?.errors[0]?.message.includes("E_INVALID_AUTH_PASSWORD")) { 65 | message = "Email and password do not match"; 66 | } else if (e.data?.errors[0]?.message) { 67 | message = e.data.errors[0].message; 68 | } else if (typeof e.data === "string") { 69 | message = e.data; 70 | } 71 | } 72 | useToast(title, message, "error"); 73 | } 74 | } 75 | --------------------------------------------------------------------------------