rename quick to util

This commit is contained in:
2026-02-04 14:07:05 +00:00
parent 941715b6a1
commit 9bd2ea980a
30 changed files with 75 additions and 63 deletions

View File

@@ -0,0 +1,27 @@
<script setup>
import { useMessagesStore } from "@/stores/messages";
const messagesStore = useMessagesStore();
const messages = computed(() => messagesStore.messages);
onMounted(() => {
messagesStore.connect();
});
onUnmounted(() => {
messagesStore.disconnect();
});
</script>
<template>
<div>
<div class="flex flex-col">
<p v-for="message in messages" :key="message.id">
{{ message.content }}
</p>
</div>
<div class="flex flex-row">
<input v-model="messageInput" @keyup.enter="sendMessage" />
<button @click="sendMessage">Send</button>
</div>
</div>
</template>

View File

@@ -0,0 +1,25 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
linkArr: {
type: Array,
required: true,
},
});
const keys = ["name", "link"];
</script>
<template>
<a
class="bdr-2 bg-bg_primary"
v-for="(row, rowIndex) in linkArr"
:key="rowIndex"
:href="row.link"
>
<p>
{{ row.name }}
</p>
</a>
</template>

View File

@@ -0,0 +1,22 @@
<script setup>
import MarkdownIt from "markdown-it";
import { katex } from "@mdit/plugin-katex";
const mdIt = MarkdownIt().use(katex);
//.use(wiki);
const props = defineProps({
source: String,
});
</script>
<template>
<div
v-html="mdIt.render(props.source)"
class="flex flex-col items-center"
></div>
</template>
<style>
@import "katex/dist/katex.min.css";
</style>

View File

@@ -0,0 +1,92 @@
<script setup>
</script>
<template>
<audio/>
<div class="musicPlayerGrid w-50">
<div class="album_cover">
<img src="/img/Untitled.png"></img>
</div>
<div class="controls">
<div class="sliders">
<div class="timeline"/>
<div class="volume"/>
</div>
<div class="buttons">
<div class="rewind"/>
<div class="playPause"/>
<div class="fastforward"/>
</div>
</div>
</div>
</template>
<style scoped>
.musicPlayerGrid {
display: grid;
grid-gap: 5px;
grid-template-rows: repeat(4, 1fr);
background-color: blue;
align-items: stretch; /* rows (block axis) */
justify-items: stretch; /* columns (inline axis) */
padding: 5px;
}
img {
width: 100%;
}
.album_cover {
grid-row: 1 / span 3;
background-color: grey;
box-sizing: border-box;
}
.controls {
width: 100%;
grid-row: 4 / span 1;
box-sizing: border-box;
display: grid;
grid-template-rows: repeat(4, 1fr);
grid-gap: 5px;
}
.sliders {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 5px;
}
.timeline {
grid-column: 1;
background-color: white;
}
.volume {
grid-column: 2;
background-color: white;
}
.buttons {
background-color: black;
grid-row: 2 / -1;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 5px;
}
.rewind {
grid-column: 1;
background-color: grey;
}
.fastforward {
grid-column: 4;
background-color: grey;
}
.playPause {
grid-column: 2/span 2;
background-color: grey;
}
</style>

View File

@@ -0,0 +1,43 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
objArr: {
type: Array,
required: true,
},
});
const resolvedColumns = computed(() => {
const keys = new Set();
for (const obj of props.objArr) {
Object.keys(obj).forEach((key) => keys.add(key));
}
return Array.from(keys).map((key) => ({
key,
label: key,
}));
});
</script>
<template>
<table>
<thead>
<tr>
<th v-for="col in resolvedColumns" :key="col.key">
{{ col.label }}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(row, rowIndex) in objArr" :key="rowIndex">
<td v-for="col in resolvedColumns" :key="col.key">
{{ row[col.key] ?? "" }}
</td>
</tr>
</tbody>
</table>
</template>

View File

@@ -0,0 +1,27 @@
<script setup>
// Array will have the form
// [ {type: string, name: string, link?: string}]
const props = defineProps({
data: {
type: Array,
required: true,
},
});
const keys = ["type", "name", "link"];
</script>
<template>
<table>
<tbody>
<tr v-for="item in data" :key="item.id">
<th>{{ item.type }}</th>
<td v-if="item.link">
<a :href="item.link">{{ item.name }}</a>
</td>
<td v-else>{{ item.name }}</td>
</tr>
</tbody>
</table>
</template>

View File

@@ -0,0 +1,23 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
linkArr: {
type: Array,
required: true,
},
});
const keys = ["name", "link"];
</script>
<template>
<RouterLink
class="bdr-2 bg-bg_primary"
v-for="(row, rowIndex) in linkArr"
:key="rowIndex"
:to="row.link"
>
{{ row.name }}
</RouterLink>
</template>

View File

@@ -0,0 +1,30 @@
<script setup>
import { ref } from "vue";
const time = ref("");
const weekday = ref("");
const day = ref("");
const month = ref("");
function updateDateTime() {
const date = new Date();
day.value = date.getDate();
time.value = date.toLocaleTimeString("en-GB", {
hour: "2-digit",
minute: "2-digit",
});
weekday.value = date.toLocaleDateString("en-GB", { weekday: "long" });
month.value = date.toLocaleDateString("en-GB", { month: "long" });
}
updateDateTime();
setInterval(updateDateTime, 60000);
</script>
<template>
<div class="flex flex-col">
<h4>{{ time }}</h4>
<h4>{{ weekday }} {{ day }}, {{ month }}</h4>
</div>
</template>

View File

@@ -0,0 +1,98 @@
<script setup>
import { ref } from "vue";
const timer = ref(null);
const finished = ref(true);
const paused = ref(true);
const minutesInput = ref(0);
const secondsInput = ref(0);
const minutes = ref(0);
const seconds = ref(0);
const audio = new Audio("/sound/auughhh.mp3");
function tick() {
seconds.value++;
if (seconds.value === 60) {
minutes.value++;
seconds.value = 0;
}
if (minutes.value >= minutesInput.value) {
if (seconds.value >= secondsInput.value) {
finished.value = true;
playFinishedSound();
clearInterval(timer.value);
}
}
}
function startTimer() {
finished.value = false;
paused.value = false;
timer.value = setInterval(tick, 1000);
}
function pauseTimer() {
if (finished.value) return;
if (paused.value) {
timer.value = setInterval(tick, 1000);
paused.value = false;
} else {
clearInterval(timer.value);
paused.value = true;
}
}
function resetTimer() {
finished.value = true;
paused.value = true;
clearInterval(timer.value);
minutes.value = 0;
seconds.value = 0;
}
function playFinishedSound() {
audio.play();
}
</script>
<template>
<div class="flex flex-col gap-1 p-1">
<h4 class="items-center">Timer</h4>
<!-- Min input and Second input-->
<div v-if="finished && paused" class="flex flex-row">
<input v-model="minutesInput" type="number" min="0" max="59" />
<input v-model="secondsInput" type="number" min="0" max="59" />
</div>
<div v-if="finished && !paused" class="flex flex-col">
<h1>Timer finished!</h1>
</div>
<div v-if="!finished && paused">
<h1>Paused</h1>
</div>
<div v-if="!finished && !paused" class="flex flex-col">
<h1>
{{ minutes.toString().padStart(2, "0") }}:{{
seconds.toString().padStart(2, "0")
}}
</h1>
<h1>
{{ minutesInput.toString().padStart(2, "0") }}:{{
secondsInput.toString().padStart(2, "0")
}}
</h1>
</div>
<div class="flex flex-col">
<button v-if="paused" @click="startTimer">Proceed</button>
<button v-if="!finished && !paused" @click="pauseTimer">
Pause
</button>
<button v-if="finished ^ paused" @click="resetTimer">Reset</button>
</div>
</div>
</template>

View File

@@ -0,0 +1,25 @@
<script setup>
import { ref } from "vue";
import LinkTable from "@/components/util/LinkTable.vue";
const props = defineProps({
linkArr: {
type: Array,
required: true,
},
title: {
type: String,
required: true,
},
});
const show_links = ref(false);
</script>
<template>
<div class="flex flex-row">
<h2>{{ title }}</h2>
<button @click="show_links = !show_links">Toggle</button>
</div>
<LinkTable v-if="show_links" :linkArr="props.linkArr" />
</template>

View File

@@ -0,0 +1,30 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
sourceArr: {
type: Array,
required: true,
},
});
function sourceType(link) {
return "video/" + link.split(".").pop();
}
const keys = ["name", "link"];
</script>
<template>
<video
v-for="(source, rowIndex) in sourceArr"
:key="rowIndex"
class="bdr-1"
width="300"
height="400"
controls
preload="none"
>
<source :src="source.link" :type="sourceType(source.link)" />
</video>
</template>

View File

@@ -0,0 +1,11 @@
<template>
<div class="a4page-portrait bdr-1 flex flex-col relative overflow-scroll">
<RouterLink to="/" class="bdr-2">
<img src="/img/memes/epic.jpeg" />
</RouterLink>
<h1>Click her, she will take you home</h1>
<span style="height: 100px"></span>
<h1>WIP</h1>
<h4>Sorry for taking you here</h4>
</div>
</template>