diff --git a/package.json b/package.json index 9f6056f..af8a402 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@types/chart.js": "^2.9.22", "@types/jquery": "^3.3.38", "@types/js-cookie": "^2.2.0", + "@types/qs": "^6.9.4", "@typescript-eslint/eslint-plugin": "^3.1.0", "@typescript-eslint/parser": "^3.1.0", "bootstrap": "^4.5.0", @@ -37,6 +38,7 @@ "open-iconic": "^1.1.1", "popper.js": "^1.14.7", "prettier": "^2.0.5", + "qs": "^6.9.4", "resolve-url-loader": "^3.1.1", "sass": "^1.26.8", "sass-loader": "^7.1.0", @@ -62,7 +64,7 @@ "stylelint --fix", "git add" ], - "*.{ts,js,vue}" : [ + "*.{ts,js,vue}": [ "eslint --fix", "git add" ], diff --git a/resources/assets/js/fetch.ts b/resources/assets/js/fetch.ts new file mode 100644 index 0000000..d683e62 --- /dev/null +++ b/resources/assets/js/fetch.ts @@ -0,0 +1,57 @@ +import { stringify } from 'qs'; + +const token = document.head.querySelector('meta[name="csrf-token"]'); +if (!token) { + console.error('CSRF token not found'); +} + +const headers = { + 'X-CSRF-TOKEN': token?.content ?? '', +}; + +type QueryParams = { [key: string]: string }; + +const joinParamsToPath = (path: string, params: QueryParams) => + Object.keys(params).length === 0 ? path : `${path}?${stringify(params)}`; + +const fetchWrapper = (path: string, options: RequestInit = {}) => + fetch(path, { + credentials: 'same-origin', + headers, + ...options, + }); + +const fetchWithJson = (path: string, body: any, options: RequestInit = {}) => + fetchWrapper(path, { + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + ...options, + }); + +const fetchWithForm = (path: string, body: any, options: RequestInit = {}) => + fetchWrapper(path, { + body: stringify(body), + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + ...options, + }); + +export const fetchGet = (path: string, params: QueryParams = {}, options: RequestInit = {}) => + fetchWrapper(joinParamsToPath(path, params), { method: 'GET', ...options }); + +export const fetchPostJson = (path: string, body: any, options: RequestInit = {}) => + fetchWithJson(path, body, { method: 'POST', ...options }); + +export const fetchPostForm = (path: string, body: any, options: RequestInit = {}) => + fetchWithForm(path, body, { method: 'POST', ...options }); + +export const fetchPutJson = (path: string, body: any, options: RequestInit = {}) => + fetchWithJson(path, body, { method: 'PUT', ...options }); + +export const fetchPutForm = (path: string, body: any, options: RequestInit = {}) => + fetchWithForm(path, body, { method: 'PUT', ...options }); + +export const fetchDeleteJson = (path: string, body: any, options: RequestInit = {}) => + fetchWithJson(path, body, { method: 'DELETE', ...options }); + +export const fetchDeleteForm = (path: string, body: any, options: RequestInit = {}) => + fetchWithForm(path, body, { method: 'DELETE', ...options }); diff --git a/resources/assets/js/tissue.ts b/resources/assets/js/tissue.ts index 1b7fe32..e059c75 100644 --- a/resources/assets/js/tissue.ts +++ b/resources/assets/js/tissue.ts @@ -1,3 +1,5 @@ +import { fetchGet } from './fetch'; + (function ($) { $.fn.linkCard = function (options) { const settings = $.extend( @@ -9,43 +11,44 @@ return this.each(function () { const $this = $(this); - $.ajax({ - url: settings.endpoint, - method: 'get', - type: 'json', - data: { - url: $this.find('a').attr('href'), - }, - }).then(function (data) { - const $metaColumn = $this.find('.col-12:last-of-type'); - const $imageColumn = $this.find('.col-12:first-of-type'); - const $title = $this.find('.card-title'); - const $desc = $this.find('.card-text'); - const $image = $imageColumn.find('img'); - if (data.title === '') { - $title.hide(); - } else { - $title.text(data.title); - } + const url = $this.find('a').attr('href'); + if (!url) { + return; + } - if (data.description === '') { - $desc.hide(); - } else { - $desc.text(data.description); - } + fetchGet(settings.endpoint, { url }) + .then((response) => response.json()) + .then((data) => { + const $metaColumn = $this.find('.col-12:last-of-type'); + const $imageColumn = $this.find('.col-12:first-of-type'); + const $title = $this.find('.card-title'); + const $desc = $this.find('.card-text'); + const $image = $imageColumn.find('img'); - if (data.image === '') { - $imageColumn.hide(); - $metaColumn.removeClass('col-md-6'); - } else { - $image.attr('src', data.image); - } + if (data.title === '') { + $title.hide(); + } else { + $title.text(data.title); + } - if (data.title !== '' || data.description !== '' || data.image !== '') { - $this.removeClass('d-none'); - } - }); + if (data.description === '') { + $desc.hide(); + } else { + $desc.text(data.description); + } + + if (data.image === '') { + $imageColumn.hide(); + $metaColumn.removeClass('col-md-6'); + } else { + $image.attr('src', data.image); + } + + if (data.title !== '' || data.description !== '' || data.image !== '') { + $this.removeClass('d-none'); + } + }); }); }; diff --git a/yarn.lock b/yarn.lock index 96ceb48..95f4a21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -849,6 +849,11 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/qs@^6.9.4": + version "6.9.4" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" + integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== + "@types/sizzle@*": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" @@ -6684,6 +6689,11 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.9.4: + version "6.9.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"