2026-05-06 23:16:09 +03:00
|
|
|
import { formatDistanceToNow, parseJSON, format, parse } from "date-fns";
|
2023-10-02 23:10:49 +03:00
|
|
|
|
|
|
|
|
export function friendlyDate(date) {
|
2026-05-06 23:16:09 +03:00
|
|
|
return formatDistanceToNow(parseJSON(date), { addSuffix: true });
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|
|
|
|
|
|
2023-10-23 22:12:17 +03:00
|
|
|
export function readableDate(date) {
|
2026-05-06 23:16:09 +03:00
|
|
|
if (!date) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
return format(parseJSON(date), "dd MMM yyyy");
|
2023-10-23 22:12:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function readableDatetime(date) {
|
2026-05-06 23:16:09 +03:00
|
|
|
if (!date) {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
2024-01-11 18:58:04 +02:00
|
|
|
|
2026-05-06 23:16:09 +03:00
|
|
|
return format(parseJSON(date), "dd MMM yyyy HH:mm");
|
2023-10-23 22:12:17 +03:00
|
|
|
}
|
|
|
|
|
|
2023-10-02 23:10:49 +03:00
|
|
|
export function stripHtml(html = "") {
|
2026-05-06 23:16:09 +03:00
|
|
|
let tmp = document.createElement("div");
|
|
|
|
|
tmp.innerHTML = html;
|
|
|
|
|
return tmp.textContent || tmp.innerText || "";
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function randomId(length = 10) {
|
2026-05-06 23:16:09 +03:00
|
|
|
return Math.random()
|
|
|
|
|
.toString(36)
|
|
|
|
|
.substring(2, length + 2);
|
2023-10-02 23:10:49 +03:00
|
|
|
}
|
2024-08-15 14:44:53 +03:00
|
|
|
|
|
|
|
|
export function clickOutside(node) {
|
2026-05-06 23:16:09 +03:00
|
|
|
const handleClick = (event) => {
|
|
|
|
|
if (node && !node.contains(event.target) && !event.defaultPrevented) {
|
|
|
|
|
node.dispatchEvent(new CustomEvent("click_outside", node));
|
2024-08-15 14:44:53 +03:00
|
|
|
}
|
2026-05-06 23:16:09 +03:00
|
|
|
};
|
2024-08-15 14:44:53 +03:00
|
|
|
|
2026-05-06 23:16:09 +03:00
|
|
|
document.addEventListener("click", handleClick, true);
|
2024-08-15 14:44:53 +03:00
|
|
|
|
2026-05-06 23:16:09 +03:00
|
|
|
return {
|
|
|
|
|
destroy() {
|
|
|
|
|
document.removeEventListener("click", handleClick, true);
|
|
|
|
|
},
|
|
|
|
|
};
|
2024-08-15 14:44:53 +03:00
|
|
|
}
|
|
|
|
|
|
2026-05-06 23:16:09 +03:00
|
|
|
export function apiFetch(url, options = {}) {
|
|
|
|
|
return fetch(url, {
|
|
|
|
|
...options,
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content,
|
|
|
|
|
...options.headers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function apiPost(url, body, options = {}) {
|
|
|
|
|
return fetch(url, {
|
|
|
|
|
...options,
|
|
|
|
|
method: "POST",
|
|
|
|
|
body: JSON.stringify(body),
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content,
|
|
|
|
|
...options.headers,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function apiGet(url, options = {}) {
|
|
|
|
|
return fetch(url, {
|
|
|
|
|
...options,
|
|
|
|
|
method: "GET",
|
|
|
|
|
headers: {
|
|
|
|
|
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content,
|
|
|
|
|
...options.headers,
|
|
|
|
|
},
|
|
|
|
|
}).then((r) => r.json());
|
|
|
|
|
}
|