rename quick to util
This commit is contained in:
27
nginx/vue/src/components/util/Chat.vue
Normal file
27
nginx/vue/src/components/util/Chat.vue
Normal 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>
|
||||
25
nginx/vue/src/components/util/LinkTable.vue
Normal file
25
nginx/vue/src/components/util/LinkTable.vue
Normal 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>
|
||||
22
nginx/vue/src/components/util/Markdown.vue
Normal file
22
nginx/vue/src/components/util/Markdown.vue
Normal 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>
|
||||
92
nginx/vue/src/components/util/MusicPlayer.vue
Normal file
92
nginx/vue/src/components/util/MusicPlayer.vue
Normal 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>
|
||||
43
nginx/vue/src/components/util/ObjectTable.vue
Normal file
43
nginx/vue/src/components/util/ObjectTable.vue
Normal 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>
|
||||
27
nginx/vue/src/components/util/OptionalLinkTable.vue
Normal file
27
nginx/vue/src/components/util/OptionalLinkTable.vue
Normal 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>
|
||||
23
nginx/vue/src/components/util/RouterTable.vue
Normal file
23
nginx/vue/src/components/util/RouterTable.vue
Normal 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>
|
||||
30
nginx/vue/src/components/util/Time.vue
Normal file
30
nginx/vue/src/components/util/Time.vue
Normal 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>
|
||||
98
nginx/vue/src/components/util/Timer.vue
Normal file
98
nginx/vue/src/components/util/Timer.vue
Normal 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>
|
||||
25
nginx/vue/src/components/util/ToggleLinkTable.vue
Normal file
25
nginx/vue/src/components/util/ToggleLinkTable.vue
Normal 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>
|
||||
30
nginx/vue/src/components/util/VideoTable.vue
Normal file
30
nginx/vue/src/components/util/VideoTable.vue
Normal 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>
|
||||
11
nginx/vue/src/components/util/Wip.vue
Normal file
11
nginx/vue/src/components/util/Wip.vue
Normal 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>
|
||||
Reference in New Issue
Block a user