<!--
https://play.tailwindcss.com/B8YFBxQAJO
-->
<div class="group relative flex h-[10em] w-[10em] items-center justify-center rounded-[1.5em] px-[0.5rem] pt-[1rem]">
<svg class="absolute left-1/2 top-[calc(50%+8px)] h-[9rem] w-[9rem] -translate-x-1/2 -translate-y-1/2" viewBox="0 0 160 160" fill="none" height="160" width="160" xmlns="http://www.w3.org/2000/svg">
<path d="M130.912 130.912a71.997 71.997 0 0 0-10.911-110.778A71.999 71.999 0 0 0 9.383 94.046a72.004 72.004 0 0 0 19.705 36.866" stroke-width="16" stroke-linecap="round" stroke="#EEDC82"></path>
<path d="M146.65 52.764A72.004 72.004 0 0 0 69.647 8.748a71.998 71.998 0 0 0-40.559 122.164" class="duration-[1s] [stroke-dasharray:100] [stroke-dashoffset:-99] group-hover:[stroke-dashoffset:0]" pathLength="100" stroke-width="16" stroke-linecap="round" stroke="#B49A18"></path>
</svg>
<p class="text-[0.75rem] font-semibold">1729/2500 Steps</p>
</div>
/*
https://javascript.plainenglish.io/7-infamous-javascript-bugs-that-shook-the-internet-3cf8f8f76098
*/
// Proper event listener cleanup to prevent memory leaks
function attachEvent() {
const btn = document.querySelector("#myButton");
const handleClick = () => console.log("Button clicked!");
btn.addEventListener("click", handleClick);
// Return a function to remove the listener and free up memory
return () => btn.removeEventListener("click", handleClick);
}
const detach = attachEvent();
detach(); // Cleanup resources
<?php
// TransportListResolver
public function getList(Order\Order $order, ?\Closure $transportListResolverModifier = null): array
{
$orderItems = $order->getItems($order::ITEM_PRODUCT);
$transportListResolver = $this->transport->getTransportSelectionResolver()
->getBaseSelection()
->setCountry($order->delivery__country_id)
->setUserGroups($this->user->isLoggedIn() ? $this->user->getRoles() : NULL)
->setWeight($order->getUniqueWeights())
->setOnlyForProduct($this->transport->listTransportOnlyForProduct($orderItems))
->setDistance(isset($order->distance) ? $order->distance : null);
if ($transportListResolverModifier) {
$transportListResolverModifier($transportListResolver);
}
$list = array_filter(
$transportListResolver->toArray(),
fn($transport) => !$transport->transport_carrier->mandatory_type_choice
|| $this->transportTypeChoice->listTransportChoiceOnlyForProduct($transport->id, $orderItems)
|| $this->transportTypeChoice->listTransportChoiceOnlyForProduct($transport->id, $orderItems) === null
);
return $list;
}
// usage in another class
// we can modify object via closure
$transportList = $this->transportListResolver->getList($order, function (TransportEshopOrderSelectionResolver $transportListResolver) {
$transportListResolver->setWithChoiceNeeded(true);
});
import {reactive} from "vue";
export default function useForm(fields) {
return reactive({
fields,
processing: false,
error: null,
async submit(submitter) {
if (this.processing) return;
this.error = null;
this.processing = true;
try {
await submitter(this.fields);
} catch (err) {
this.error = err;
}
this.processing = false;
},
});
}
// https://tallpad.com/series/vuejs-misc/lessons/vue-state-and-localstorage-perfect-sync-made-simple
// onMounted => SSR
import {onMounted, ref, watch} from "vue";
export default function (initialValue, key) {
const val = ref(initialValue);
onMounted(() => {
const storageVal = window.localStorage.getItem(key);
if (storageVal) {
val.value = JSON.parse(storageVal);
}
watch(
val,
val => {
window.localStorage.setItem(key, JSON.stringify(val));
},
{deep: true}
);
});
return val;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tallpad</title>
</head>
<body>
<div id="app"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_API_KEY&libraries=places"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
const img = document.querySelector('img')
const tempImg = new Image()
tempImg.src = 'https://masoprofit.cz/storage/images/1600x2000/41847.png.webp'
tempImg.decode().then(() => {
img.src = tempImg.src
}).catch(e => {
console.log(e)
})
// https://tallpad.com/series/vuejs-misc/lessons/table-of-contents-component-using-vuejs
<script setup>
import {onMounted, ref, computed} from "vue";
import TocList from "./TocList.vue";
import {slugifyWithCounter} from "@sindresorhus/slugify";
const props = defineProps({
contentSelector: {
type: String,
required: true,
},
});
const slugify = slugifyWithCounter();
const headings = ref([]);
onMounted(() => {
window.document
.querySelector(props.contentSelector)
.querySelectorAll("h1, h2, h3, h4, h5, h6")
.forEach(el => {
let id = slugify(el.innerText);
el.setAttribute("id", id);
headings.value.push({
id: id,
level: parseInt(el.tagName.charAt(1), 10),
content: el.innerText,
subheadings: [],
});
});
});
const groupedHeadings = computed(() => {
let items = [...headings.value];
for (let i = items.length - 1; i >= 0; i--) {
let currentItem = items[i];
let parentItem = items.findLast((item, index) => {
return item.level < currentItem.level && index < i;
});
if (parentItem) {
parentItem.subheadings.unshift(currentItem);
items.splice(i, 1);
}
}
return items;
});
</script>
<template>
<div class="bg-slate-50 -mx-6 p-6" v-if="groupedHeadings.length">
<h3
class="border-b-2 border-slate-300 inline-block uppercase font-bold tracking-wide text-slate-800 mb-5"
>
Contents:
</h3>
<TocList :items="groupedHeadings" />
</div>
</template>
// https://tallpad.com/series/vuejs-misc/lessons/build-an-alert-component-using-vue-tailwindcss-and-cva
<script setup>
import {InformationCircleIcon, XMarkIcon, CheckCircleIcon, ExclamationTriangleIcon, XCircleIcon} from "@heroicons/vue/20/solid/index.js";
import {computed} from "vue";
import {cva} from "class-variance-authority";
const props = defineProps({
intent: {
type: String,
validator(value) {
return ["info", "success", "danger", "warning"].includes(value);
},
default: "info",
},
title: String,
show: {
type: Boolean,
default: true,
},
onDismiss: Function,
});
const containerClass = computed(() => {
return cva("flex p-4 rounded-md space-x-3", {
variants: {
intent: {
info: "bg-blue-100",
success: "bg-green-100",
warning: "bg-orange-100",
danger: "bg-red-100",
},
},
})({
intent: props.intent,
});
});
const iconClass = computed(() => {
return cva("w-6 h-6", {
variants: {
intent: {
info: "text-blue-700",
success: "text-green-600",
warning: "text-orange-400",
danger: "text-red-500",
},
},
})({
intent: props.intent,
});
});
const titleClass = computed(() => {
return cva("font-medium", {
variants: {
intent: {
info: "text-blue-900",
success: "text-green-900",
warning: "text-orange-900",
danger: "text-red-900"
},
},
})({
intent: props.intent,
});
});
const contentClass = computed(() => {
return cva("text-sm", {
variants: {
intent: {
info: "text-blue-800",
success: "text-green-800",
warning: "text-orange-800",
danger: "text-red-800",
},
},
})({
intent: props.intent,
});
});
const closeButtonClass = computed(() => {
return cva("p-0.5 rounded-md -m-1", {
variants: {
intent: {
info: "text-blue-900/70 hover:text-blue-900 hover:bg-blue-200",
success: "text-green-900/70 hover:text-green-900 hover:bg-green-200",
warning: "text-orange-900/70 hover:text-orange-900 hover:bg-orange-200",
danger: "text-red-900/70 hover:text-red-900 hover:bg-red-200",
},
},
})({
intent: props.intent,
});
});
const iconComponent = computed(() => {
const icons = {
success: CheckCircleIcon,
warning: ExclamationTriangleIcon,
danger: XCircleIcon,
info: InformationCircleIcon,
};
return icons[props.intent];
});
function dismiss() {
if (props.onDismiss) {
props.onDismiss();
}
}
</script>
<template>
<div v-if="props.show" :class="containerClass">
<div class="shrink-0">
<component :is="iconComponent" :class="iconClass" />
</div>
<div class="flex-1 space-y-2">
<h2 :class="titleClass">
{{ props.title }}
</h2>
<div :class="contentClass"><slot /></div>
</div>
<div class="shrink-0" v-if="props.onDismiss">
<button @click="dismiss()" :class="closeButtonClass">
<XMarkIcon class="w-6 h-6" />
</button>
</div>
</div>
</template>