Adding prestyled base tags and testing admin dashboard

This commit is contained in:
2024-11-04 16:34:11 +01:00
parent 633231f821
commit 0105a6aaea
36 changed files with 643 additions and 18 deletions

View File

@@ -0,0 +1,50 @@
<template>
<slot v-bind="$attrs"></slot>
<!-- <Suspense suspensible>
<NuxtLink no-prefetch class="text-accent-blue inline-flex items-center" v-if="data && data[0]"
:to="{ path: `/explorer/${project}/${data[0].path}`, hash: hash }" :class="class">
<PreviewContent :project="project" :path="data[0].path" :anchor="hash">
<template #default>
<slot v-bind="$attrs"></slot>
<Icon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`icons/link-${data[0].type.toLowerCase()}`" />
</template>
</PreviewContent>
</NuxtLink>
<NuxtLink no-prefetch v-else-if="href" :to="href" :class="class" class="text-accent-blue inline-flex items-center">
<slot v-bind="$attrs"></slot>
<Icon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`icons/link-${data[0].type.toLowerCase()}`" />
</NuxtLink>
<slot :class="class" v-else v-bind="$attrs"></slot>
</Suspense> -->
</template>
<!--<script setup lang="ts">
import { parseURL } from 'ufo';
const props = defineProps({
href: {
type: String,
required: false,
},
class: {
type: String,
required: false,
}
});
const route = useRoute();
const { hash, pathname, protocol } = parseURL(props.href);
const project = computed(() => parseInt(Array.isArray(route.params.projectId) ? '0' : route.params.projectId));
const data = ref();
if(!!pathname && !protocol)
{
data.value = await $fetch(`/api/project/${project.value}/file`, {
query: {
search: `%${pathname}`
},
ignoreResponseError: true,
});
}
</script>-->

View File

@@ -0,0 +1,182 @@
<template>
<blockquote ref="el">
<slot />
</blockquote>
</template>
<!-- <script setup lang="ts">
const attrs = useAttrs(), el = ref<HTMLQuoteElement>(), title = ref<Element | null>(null);
onMounted(() => {
if(el && el.value && attrs.hasOwnProperty("dataCalloutFold"))
{
title.value = el.value.querySelector('.callout-title');
title.value?.addEventListener('click', toggle);
}
});
onUnmounted(() => {
title.value?.removeEventListener('click', toggle);
})
function toggle() {
el.value?.classList?.toggle('is-collapsed');
}
</script>
<style>
blockquote:not(.callout)
{
@apply ps-4;
@apply my-4;
@apply relative;
@apply before:absolute;
@apply before:-top-1;
@apply before:-bottom-1;
@apply before:left-0;
@apply before:w-1;
@apply before:bg-light-30;
@apply dark:before:bg-dark-30;
}
blockquote:empty
{
@apply before:hidden;
}
.callout {
@apply bg-light-blue;
@apply dark:bg-dark-blue;
}
.callout.is-collapsible .callout-title
{
@apply cursor-pointer;
}
.callout .fold
{
@apply transition-transform;
}
.callout.is-collapsed .fold
{
@apply -rotate-90;
}
.callout.is-collapsed > p
{
@apply hidden;
}
.callout[datacallout="abstract"],
.callout[datacallout="summary"],
.callout[datacallout="tldr"] {
@apply bg-light-cyan;
@apply dark:bg-dark-cyan;
@apply text-light-cyan;
@apply dark:text-dark-cyan;
}
.callout[datacallout="info"] {
@apply bg-light-blue;
@apply dark:bg-dark-blue;
@apply text-light-blue;
@apply dark:text-dark-blue;
}
.callout[datacallout="todo"] {
@apply bg-light-blue;
@apply dark:bg-dark-blue;
@apply text-light-blue;
@apply dark:text-dark-blue;
}
.callout[datacallout="important"] {
@apply bg-light-cyan;
@apply dark:bg-dark-cyan;
@apply text-light-cyan;
@apply dark:text-dark-cyan;
}
.callout[datacallout="tip"],
.callout[datacallout="hint"] {
@apply bg-light-cyan;
@apply dark:bg-dark-cyan;
@apply text-light-cyan;
@apply dark:text-dark-cyan;
}
.callout[datacallout="success"],
.callout[datacallout="check"],
.callout[datacallout="done"] {
@apply bg-light-green;
@apply dark:bg-dark-green;
@apply text-light-green;
@apply dark:text-dark-green;
}
.callout[datacallout="question"],
.callout[datacallout="help"],
.callout[datacallout="faq"] {
@apply bg-light-orange;
@apply dark:bg-dark-orange;
@apply text-light-orange;
@apply dark:text-dark-orange;
}
.callout[datacallout="warning"],
.callout[datacallout="caution"],
.callout[datacallout="attention"] {
@apply bg-light-orange;
@apply dark:bg-dark-orange;
@apply text-light-orange;
@apply dark:text-dark-orange;
}
.callout[datacallout="failure"],
.callout[datacallout="fail"],
.callout[datacallout="missing"] {
@apply bg-light-red;
@apply dark:bg-dark-red;
@apply text-light-red;
@apply dark:text-dark-red;
}
.callout[datacallout="danger"],
.callout[datacallout="error"] {
@apply bg-light-red;
@apply dark:bg-dark-red;
@apply text-light-red;
@apply dark:text-dark-red;
}
.callout[datacallout="bug"] {
@apply bg-light-red;
@apply dark:bg-dark-red;
@apply text-light-red;
@apply dark:text-dark-red;
}
.callout[datacallout="example"] {
@apply bg-light-purple;
@apply dark:bg-dark-purple;
@apply text-light-purple;
@apply dark:text-dark-purple;
}
.callout
{
@apply overflow-hidden;
@apply my-4;
@apply p-3;
@apply ps-6;
@apply bg-blend-lighten;
@apply !bg-opacity-25;
@apply border-l-4;
@apply inline-block;
@apply pe-8;
}
.callout-icon
{
@apply w-6;
@apply h-6;
@apply stroke-2;
}
.callout-title
{
@apply flex;
@apply items-center;
@apply gap-2;
}
.callout-title-inner
{
@apply inline-block;
@apply font-bold;
}
.callout > p
{
@apply mt-2;
@apply font-semibold;
}
</style> -->

View File

@@ -0,0 +1,3 @@
<template>
<code><slot /></code>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<em>
<slot />
</em>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<h1 :id="parseId(id)" class="text-5xl font-thin mt-3 mb-8 first:pt-0 pt-2 relative sm:right-8 right-4">
<slot />
</h1>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
</script>

View File

@@ -0,0 +1,11 @@
<template>
<h2 :id="parseId(id)" class="text-4xl font-semibold mt-3 mb-6 ms-1 first:pt-0 pt-2 relative sm:right-8 right-4">
<slot />
</h2>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
const generate = computed(() => props.id)
</script>

View File

@@ -0,0 +1,11 @@
<template>
<h3 :id="parseId(id)" class="text-2xl font-bold mt-2 mb-4">
<slot />
</h3>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
const generate = computed(() => props.id)
</script>

View File

@@ -0,0 +1,9 @@
<template>
<h4 :id="parseId(id)" class="text-xl font-semibold my-2" style="font-variant: small-caps;">
<slot />
</h4>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
</script>

View File

@@ -0,0 +1,11 @@
<template>
<h5 :id="parseId(id)" class="text-lg font-semibold my-1">
<slot />
</h5>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
const generate = computed(() => props.id)
</script>

View File

@@ -0,0 +1,11 @@
<template>
<h6 :id="parseId(id)">
<slot />
</h6>
</template>
<script setup lang="ts">
const props = defineProps<{ id?: string }>()
const generate = computed(() => props.id)
</script>

View File

@@ -0,0 +1,3 @@
<template>
<Separator class="border-light-35 dark:border-dark-35 m-4" />
</template>

View File

@@ -0,0 +1,42 @@
<template>
<img
:src="refinedSrc"
:alt="alt"
:width="width"
:height="height"
/>
</template>
<script setup lang="ts">
import { withTrailingSlash, withLeadingSlash, joinURL } from 'ufo'
import { useRuntimeConfig, computed, resolveComponent } from '#imports'
const props = defineProps({
src: {
type: String,
default: ''
},
alt: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: undefined
},
height: {
type: [String, Number],
default: undefined
}
})
const refinedSrc = computed(() => {
if (props.src?.startsWith('/') && !props.src.startsWith('//')) {
const _base = withLeadingSlash(withTrailingSlash(useRuntimeConfig().app.baseURL))
if (_base !== '/' && !props.src.startsWith(_base)) {
return joinURL(_base, props.src)
}
}
return props.src
})
</script>

View File

@@ -0,0 +1,3 @@
<template>
<li class="before:absolute before:top-2 before:left-0 before:inline-block before:w-2 before:h-2 before:rounded before:bg-light-40 dark:before:bg-dark-40 relative ps-4"><slot /></li>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<ol>
<slot />
</ol>
</template>

View File

@@ -0,0 +1,12 @@
<template>
<p><slot /></p>
</template>
<style>
.text-comment
{
@apply text-light-50;
@apply dark:text-dark-50;
@apply text-sm;
}
</style>

View File

@@ -0,0 +1,36 @@
<template>
<pre :class="$props.class"><slot /></pre>
</template>
<script setup lang="ts">
defineProps({
code: {
type: String,
default: ''
},
language: {
type: String,
default: null
},
filename: {
type: String,
default: null
},
highlights: {
type: Array as () => number[],
default: () => []
},
meta: {
type: String,
default: null
},
class: {
type: String,
default: null
}
})
</script>
<style>
pre code .line{display:block}
</style>

View File

@@ -0,0 +1,15 @@
<template>
<div v-if="isDev">
Rendering the <code>script</code> element is dangerous and is disabled by default. Consider implementing your own <code>ProseScript</code> element to have control over script rendering.
</div>
</template>
<script setup lang="ts">
defineProps({
src: {
type: String,
default: ''
}
})
const isDev = import.meta.dev
</script>

View File

@@ -0,0 +1,5 @@
<template>
<strong>
<slot />
</strong>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<table class="mx-4 my-8 border-collapse border border-light-35 dark:border-dark-35">
<slot />
</table>
</template>

View File

@@ -0,0 +1,55 @@
<template>
<!-- <HoverPopup @before-show="fetch">
<template #content>
<Suspense suspensible>
<div class="mw-[400px]">
<div v-if="fetched === false" class="loading w-[400px] h-[150px]"></div>
<template v-else-if="!!data">
<div v-if="data.description" class="pb-4 pt-3 px-8">
<span class="text-2xl font-semibold">#{{ data.tag }}</span>
<Markdown :content="data.description"></Markdown>
</div>
<div class="h-100 w-100 flex flex-1 flex-col justify-center items-center" v-else>
<div class="text-3xl font-extralight tracking-wide text-light-60 dark:text-dark-60">Fichier vide</div>
<div class="text-lg text-light-60 dark:text-dark-60">Cette page est vide</div>
</div>
</template>
<div class="h-100 w-100 flex flex-1 flex-col justify-center items-center" v-else>
<div class="text-3xl font-extralight tracking-wide text-light-60 dark:text-dark-60">Impossible d'afficher</div>
<div class="text-lg text-light-60 dark:text-dark-60">Cette page est impossible à traiter</div>
</div>
</div>
<template #fallback><div class="loading w-[400px] h-[150px]"></div></template>
</Suspense>
</template>
<template #default>
<span class="before:content-['#'] cursor-default bg-accent-blue bg-opacity-10 hover:bg-opacity-20 text-accent-blue text-sm px-1 ms-1 pb-0.5 rounded-full rounded-se-none border border-accent-blue border-opacity-30">
<slot></slot>
</span>
</template>
</HoverPopup> -->
<slot />
</template>
<!-- <script setup lang="ts">
import type { Tag } from '~/types/api';
const { tag } = defineProps({
tag: {
type: String,
required: true,
}
});
const data = ref<Tag>(), fetched = ref(false);
const route = useRoute();
const project = computed(() => parseInt(Array.isArray(route.params.projectId) ? '0' : route.params.projectId));
async function fetch()
{
if(fetched.value)
return;
data.value = await $fetch(`/api/project/${project.value}/tags/${encodeURIComponent(tag)}`);
fetched.value = true;
}
</script> -->

View File

@@ -0,0 +1,5 @@
<template>
<tbody>
<slot />
</tbody>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<td class="border border-light-35 dark:border-dark-35 py-1 px-2">
<slot />
</td>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<th class="border border-light-35 dark:border-dark-35 px-4 first:pt-0">
<slot />
</th>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<thead>
<slot />
</thead>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<tr>
<slot />
</tr>
</template>

View File

@@ -0,0 +1,5 @@
<template>
<ul>
<slot />
</ul>
</template>