Browse Source

Delete todo app, add blog website

master
Riyyi 3 weeks ago
parent
commit
ebad4817be
  1. 2320
      bun.lock
  2. 39
      content/articles/first.md
  3. 30
      nuxt.config.ts
  4. 1131
      package-lock.json
  5. 17
      package.json
  6. 37
      src/assets/css/style.css
  7. 28
      src/components.d.ts
  8. 6
      src/components/ExampleComponent.vue
  9. 9
      src/components/Shared/Footer.vue
  10. 87
      src/components/Shared/NavMenu.vue
  11. 18
      src/components/Table/SortingColumn.vue
  12. 59
      src/components/Todo/Add.vue
  13. 94
      src/components/Todo/Browse.vue
  14. 8
      src/layouts/default.vue
  15. 35
      src/pages/articles/[slug].vue
  16. 191
      src/pages/todos.vue
  17. 6
      tsconfig.json

2320
bun.lock

File diff suppressed because it is too large Load Diff

39
content/articles/first.md

@ -7,6 +7,41 @@ description: "This is a test article."
This is a test article. This is a test article.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum a tempor
dolor. Nullam mattis sapien vel finibus dignissim. Etiam et diam ultrices,
aliquam enim nec, commodo sem. Cras ut faucibus risus. Suspendisse vel faucibus
ipsum. Duis vel orci nec arcu porttitor fermentum eu quis est. Phasellus elit
odio, elementum ac placerat at, feugiat sit amet sapien.
Vestibulum dapibus pharetra metus. Integer volutpat lacus nec enim euismod, id
dignissim felis rhoncus. Cras commodo tempus turpis, eu vehicula mi lacinia
eget. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos. Integer rhoncus dolor ut dolor gravida vestibulum. Ut
dignissim orci a ornare ullamcorper. Nam facilisis mauris sit amet nunc
fermentum pretium. Nullam in nisi at risus luctus viverra. Mauris non congue
dolor, vel finibus lectus. Nam quis leo pretium, sodales augue et, dictum sem.
Curabitur velit ante, imperdiet in eros eu, iaculis gravida risus. Nullam ut
feugiat eros, viverra vehicula sem. Aliquam finibus mi magna, eu fringilla
tellus ullamcorper vel. Fusce eget auctor mi. Mauris venenatis pellentesque
arcu. Nam ac diam sem. Nulla suscipit sed risus non vehicula. Cras molestie
lectus et tincidunt tempor. Ut tempus lorem id augue semper convallis. Aliquam
vel dui quis dolor cursus faucibus eget a mi. Curabitur tempus justo diam, a
facilisis ligula tincidunt viverra. Donec sodales quis dolor at dignissim.
Nullam placerat vitae urna quis bibendum.
Integer a magna a velit bibendum mollis. Donec lobortis molestie diam at rutrum.
Nunc viverra gravida metus at facilisis. Nulla sit amet erat sodales, commodo
elit sed, ultrices magna. Aliquam vel purus fringilla, gravida enim quis,
aliquam augue. Duis interdum et erat nec feugiat. Praesent vitae lacinia leo,
non suscipit purus.
Aenean massa magna, imperdiet id ex quis, mollis auctor lectus. Cras velit
nulla, volutpat eu neque id, semper venenatis urna. Integer in blandit ex, non
scelerisque nisi. Ut sagittis tincidunt enim at volutpat. Sed hendrerit metus ac
interdum laoreet. In rutrum turpis in nulla vulputate suscipit. Nunc dictum nisl
id magna laoreet dapibus.
## Component Rendering ## Component Rendering
::ExampleComponent ::ExampleComponent
@ -36,9 +71,9 @@ protected static $router;
$path = parse_url($_SERVER['REQUEST_URI'])['path']; $path = parse_url($_SERVER['REQUEST_URI'])['path'];
``` ```
Inline `hightlight`. Inline `hightlight` looks like so.
`const code: string = 'highlighted code inline'`{lang="ts"} Inline highlight with language `const code: string = 'highlighted code inline'`{lang="ts"} like this.
- An - An
- Unordered - Unordered

30
nuxt.config.ts

@ -1,4 +1,6 @@
import Aura from "@primevue/themes/aura"; import Icons from "unplugin-icons/vite"
import IconsResolver from "unplugin-icons/resolver"
import ViteComponents from "unplugin-vue-components/vite"
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
@ -17,7 +19,7 @@ export default defineNuxtConfig({
} }
}, },
css: [ css: [
"primeicons/primeicons.css", "bootstrap/dist/css/bootstrap.min.css",
"~/assets/css/style.css" "~/assets/css/style.css"
], ],
devtools: { enabled: true }, devtools: { enabled: true },
@ -25,11 +27,12 @@ export default defineNuxtConfig({
public: "../public" public: "../public"
}, },
modules: [ modules: [
"@bootstrap-vue-next/nuxt",
"@nuxt/content", "@nuxt/content",
"@nuxt/eslint", "@nuxt/eslint",
"@pinia/nuxt", "@pinia/nuxt",
"@primevue/nuxt-module",
"pinia-plugin-persistedstate/nuxt", "pinia-plugin-persistedstate/nuxt",
"unplugin-icons/nuxt"
], ],
pinia: { pinia: {
storesDirs: ["src/stores/**"] // also auto-import nested directories storesDirs: ["src/stores/**"] // also auto-import nested directories
@ -42,13 +45,18 @@ export default defineNuxtConfig({
secure: process.env.NODE_ENV !== "development" // only send over HTTPS secure: process.env.NODE_ENV !== "development" // only send over HTTPS
} }
}, },
primevue: {
options: {
theme: {
preset: Aura
}
}
},
srcDir: "src/", srcDir: "src/",
ssr: false ssr: false,
vite: {
plugins: [
ViteComponents({
resolvers: [IconsResolver()],
dts: true
}),
Icons({
compiler: "vue3",
autoInstall: true,
}),
],
},
}) })

1131
package-lock.json generated

File diff suppressed because it is too large Load Diff

17
package.json

@ -11,25 +11,28 @@
}, },
"dependencies": { "dependencies": {
"@pinia/nuxt": "^0.10.1", "@pinia/nuxt": "^0.10.1",
"@primevue/forms": "^4.2.3",
"@primevue/themes": "^4.2.3",
"nuxt": "^3.14.1592",
"pinia-plugin-persistedstate": "^4.1.3", "pinia-plugin-persistedstate": "^4.1.3",
"primeicons": "^7.0.0",
"primevue": "^4.2.3",
"uuid": "^11.0.3", "uuid": "^11.0.3",
"vue": "latest", "vue": "latest",
"vue-router": "latest", "vue-router": "latest",
"zod": "^3.23.8" "zod": "^3.23.8"
}, },
"devDependencies": { "devDependencies": {
"@bootstrap-vue-next/nuxt": "^0.28.3",
"@iconify-json/bi": "^1.2.2",
"@iconify-json/fa": "^1.2.1",
"@nuxt/content": "^3.4.0", "@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.2.0", "@nuxt/eslint": "^1.2.0",
"@primevue/nuxt-module": "^4.2.3",
"@types/bun": "latest", "@types/bun": "latest",
"@vue/compiler-sfc": "^3.5.13",
"@vue/language-server": "^2.1.10", "@vue/language-server": "^2.1.10",
"@vue/typescript-plugin": "^2.1.10", "@vue/typescript-plugin": "^2.1.10",
"typescript": "^5.7.2" "bootstrap": "^5.3.3",
"bootstrap-vue-next": "^0.28.3",
"nuxt": "^3.14.1592",
"typescript": "^5.7.2",
"unplugin-icons": "^22.1.0",
"unplugin-vue-components": "^28.4.1"
}, },
"trustedDependencies": [ "trustedDependencies": [
"@parcel/watcher" "@parcel/watcher"

37
src/assets/css/style.css

@ -1,7 +1,42 @@
/*----------------------------------------*/ /*----------------------------------------*/
/* General */ /* General */
body { html {
font-family: "Segoe UI", "DejaVu Sans", sans-serif; font-family: "Segoe UI", "DejaVu Sans", sans-serif;
scroll-behavior: smooth; scroll-behavior: smooth;
} }
body {
background-color: #f4f4f4;
}
nav {
box-shadow: 0 .25rem .5rem rgba(0,0,0,.28) !important;
}
/* Main content */
/*----------------------------------------*/
.container {
margin: 56px auto 0 auto;
}
.content {
position: relative;
min-height: calc(100vh - 104px - .5rem);
padding: 20px 20px 50px 20px;
background-color: #fff;
}
a:hover {
color: #818080 !important;
}
/* Footer */
/*----------------------------------------*/
footer {
text-align: center;
color: #909090;
}

28
src/components.d.ts vendored

@ -0,0 +1,28 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
IBi0Circle: typeof import('~icons/bi/0-circle')['default']
IBiActivity: typeof import('~icons/bi/activity')['default']
IFaAngellist: typeof import('~icons/fa/angellist')['default']
IFaCheck: typeof import('~icons/fa/check')['default']
IFaClone: typeof import('~icons/fa/clone')['default']
IFaCoffee: typeof import('~icons/fa/coffee')['default']
IFaCope: typeof import('~icons/fa/cope')['default']
IFaCopy: typeof import('~icons/fa/copy')['default']
IFaGithub: typeof import('~icons/fa/github')['default']
IFaGitlab: typeof import('~icons/fa/gitlab')['default']
IFaHome: typeof import('~icons/fa/home')['default']
IFaLink: typeof import('~icons/fa/link')['default']
IFaLinkedinSquare: typeof import('~icons/fa/linkedin-square')['default']
IMdiAccountBox: typeof import('~icons/mdi/account-box')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

6
src/components/ExampleComponent.vue

@ -1,11 +1,13 @@
<template> <template>
<div> <div>
<h2 v-if="$slots.namedslot"> <strong v-if="$slots.namedslot">
<slot name="namedslot" mdc-unwrap="p" /> <slot name="namedslot" mdc-unwrap="p" />
</h2> </strong>
<h2 v-else>Broken Slot</h2> <h2 v-else>Broken Slot</h2>
<p>
<slot mdc-unwrap="p" /> <slot mdc-unwrap="p" />
</p>
</div> </div>
</template> </template>

9
src/components/Shared/Footer.vue

@ -1,2 +1,11 @@
<template> <template>
<footer class="row mb-2">
<div class="col-12">
© {{ year }} Rick van Vonderen
</div>
</footer>
</template> </template>
<script setup lang="ts">
const year = new Date().getFullYear();
</script>

87
src/components/Shared/NavMenu.vue

@ -1,61 +1,30 @@
<template> <template>
<div class="card"> <BNavbar v-b-color-mode="'dark'" toggleable="lg" variant="dark" fixed="top">
<Menubar :model="items"> <BNavbarBrand to="/">
<template #item="{ item, props, hasSubmenu }"> <IFaHome /> Home
<router-link v-if="item.route" v-slot="{ href, navigate }" :to="item.route" custom> </BNavbarBrand>
<a v-ripple :href="href" v-bind="props.action" @click="navigate"> <BNavbarToggle target="nav-collapse" />
<span :class="item.icon" /> <BCollapse id="nav-collapse" is-nav>
<span>{{ item.label }}</span> <!-- Left aligned nav items -->
</a> <BNavbarNav>
</router-link> <BNavItem to="/articles">Articles</BNavItem>
<a v-else v-ripple :href="item.url" :target="item.target" v-bind="props.action"> <BNavItem to="/todos">Todos</BNavItem>
<span :class="item.icon" /> </BNavbarNav>
<span>{{ item.label }}</span> <!-- Right aligned nav items -->
<span v-if="hasSubmenu" class="pi pi-fw pi-angle-down" /> <BNavbarNav class="ms-auto mb-2 mb-lg-0">
</a> <BNavItem href="https://git.riyyi.com/riyyi" target="_blank">
<IFaCoffee /> Gitea
</BNavItem>
<BNavItem href="https://github.com/riyyi" target="_blank">
<IFaGithub /> Github
</BNavItem>
<BNavItem href="https://gitlab.com/riyyi" target="_blank">
<IFaGitlab /> Gitlab
</BNavItem>
<BNavItem href="https://linkedin.com/in/rickvanvonderen" target="_blank">Linked
<IFaLinkedinSquare />
</BNavItem>
</BNavbarNav>
</BCollapse>
</BNavbar>
</template> </template>
</Menubar>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const currentDate = new Date().toLocaleString("nl-NL");
const items = ref([
{
label: "Home",
icon: "pi pi-home",
route: "/"
},
{
label: "Todos",
icon: "pi pi-check",
command: () => {
router.push("/todos");
}
},
{
label: "Articles",
icon: "pi pi-link",
route: "/articles"
},
{
label: "Service",
icon: "pi pi-link",
route: "#"
},
{
label: "Contact",
icon: "pi pi-link",
route: "#"
},
{
label: "Date: " + currentDate,
},
]);
</script>

18
src/components/Table/SortingColumn.vue

@ -1,18 +0,0 @@
<template>
adasda
<Column field="title">
<template #header>
<span @click="toggleSorting('title')" class="p-datatable-column-title">Title&nbsp;
<span :class="['pi', sorting.title === 'asc' ? 'pi-arrow-circle-down' : 'pi-arrow-circle-up']"></span>
</span>
</template>
</Column>
</template>
<script setup lang="ts">
const sorting = defineModel<Record<string, string>>({ required: true });
function toggleSorting(key: string) {
sorting.value[key] = sorting.value[key] === 'asc' ? 'desc' : 'asc';
};
</script>

59
src/components/Todo/Add.vue

@ -1,59 +0,0 @@
<template>
<Form v-slot="$form" ref="formRef" :initialValues :resolver @submit="onFormSubmit"
class="flex flex-col gap-4 w-full sm:w-56">
<!-- {{ $form }} -->
<div class="flex flex-col gap-1">
<InputText @input="initial = false;" v-model="formData.title" name="title" type="text" placeholder="Title"
autocomplete="off" fluid />
<Message v-if="$form.title?.invalid" severity="error" size="small" variant="simple">
{{ $form.title.error?.message }}
</Message>
</div>
<Button :disabled="initial || !$form.valid" class="fr" type="submit" severity="secondary" label="Submit" />
</Form>
</template>
<script setup lang="ts">
import { useTodoStore } from "@/stores/todoStore";
import { todoSchema } from "@/schemas/todo";
import { zodResolver } from '@primevue/forms/resolvers/zod';
import { v4 as uuidv4 } from "uuid";
import { type FormSubmitEvent } from "@primevue/forms/form";
const store = useTodoStore();
const toast = useToast();
const resolver = zodResolver(todoSchema);
const initial = ref(true); // makes submit button disabled
const initialValues = ref({
title: ""
});
const formRef = ref<HTMLElement | null>(null);
const formData = ref({ ...initialValues.value }); // copy data from initialValues
async function onFormSubmit(e: FormSubmitEvent) {
if (e.valid) {
toast.add({ severity: "success", summary: "Todo added", life: 3000 });
store.todos.push({
id: uuidv4(),
title: e.values?.title || e.states?.title.value
});
// Reset the form
initial.value = true;
formData.value = { ...initialValues.value }; // copy data from initialValues
}
else {
toast.add({ severity: "error", summary: "Invalid request", life: 3000 });
}
};
</script>
<style scoped>
.fr {
float: right;
}
</style>

94
src/components/Todo/Browse.vue

@ -1,94 +0,0 @@
<template>
<div class="card">
<ConfirmDialog></ConfirmDialog>
<DataTable :value="computedTodos" :lazy="true" tableStyle="min-width: 50rem" removableSort
:sortMode="'multiple'" v-model:multiSortMeta="multiSortMeta">
<Column field="number" header="#" />
<Column field="id" header="ID" sortable />
<Column field="title" header="Title" sortable />
<Column header="Modifier">
<template #body="slotProps">
<a @click="removeTodo(slotProps.data.id)" v-tooltip.top="'Delete'" class="pointer">
<span class="pi pi-trash" style="color: var(--p-red-600);"></span>
</a>
</template>
</Column>
</DataTable>
</div>
</template>
<script setup lang="ts">
import { useConfirm } from "primevue/useconfirm";
import { useToast } from "primevue/usetoast";
import { useTodoStore } from "@/stores/todoStore";
import type { DataTableSortMeta } from "primevue/datatable";
import type { Todo } from "@/schemas/todo";
const confirm = useConfirm();
const store = useTodoStore();
const toast = useToast();
// Reactive bindings for sorting
const multiSortMeta = ref<DataTableSortMeta[]>([]);
function sortTodos(): Todo[] {
let todos: Todo[] = JSON.parse(JSON.stringify(store.todos)); // deep copy
// Loop in reverse order to apply the sorting correctly
for (let i = multiSortMeta.value.length - 1; i >= 0; i--) {
const sort: DataTableSortMeta = multiSortMeta.value[i];
const value = (item: Todo): string => {
if (typeof sort.field === "string") {
return item[sort.field as keyof Todo] || "";
}
else if (typeof sort.field === "function") {
return sort.field(item) || "";
}
return "";
};
todos.sort((a, b) => sort.order! * value(a).localeCompare(value(b)));
}
return todos;
}
const computedTodos = computed(() => {
return sortTodos().map((todo, index) => ({
number: index + 1,
...todo
}));
});
const removeTodo = (id: String) => {
confirm.require({
message: "Do you want to delete this todo?",
header: "Confirmation",
icon: "pi pi-info-circle",
rejectLabel: "Cancel",
rejectProps: {
label: "Cancel",
severity: "secondary",
outlined: true
},
acceptProps: {
label: "Delete",
severity: "danger"
},
accept: () => {
toast.add({ severity: "info", summary: "Confirmed", detail: "Todo deleted", life: 3000 });
store.todos = store.todos.filter(todo => todo.id !== id);
},
reject: () => {}
});
};
</script>
<style scoped>
.pointer {
cursor: pointer;
}
</style>

8
src/layouts/default.vue

@ -1,5 +1,13 @@
<template> <template>
<SharedHeader /> <SharedHeader />
<div class="container">
<div class="row">
<div class="col-12">
<div class="content shadow p-4 mb-4">
<slot /> <slot />
</div>
</div>
</div>
<SharedFooter /> <SharedFooter />
</div>
</template> </template>

35
src/pages/articles/[slug].vue

@ -12,6 +12,41 @@
</div> </div>
</template> </template>
<style scoped>
/* Target element in child components with :deep */
/* Select any <a> inside a <h> */
:deep(:is(h1, h2, h3, h4, h5, h6) > a) {
color: inherit;
text-decoration: none;
}
/* Select <pre class="shiki"> */
:deep(pre.shiki) {
display: flex;
justify-content: space-between;
margin-bottom: 1rem;
padding: 1rem;
background-color: #f6f8fa;
}
/* Select <code> and <code class="shiki"> */
:deep(code:not(pre code)) {
padding: .2em .4em;
margin: 0;
font-size: 85%;
white-space: break-spaces;
background-color: #818b981f;
border-radius: 6px;
}
/* Select <code> */
:deep(code:not(.shiki):not(pre code)) {
/* reset font to black */
color: inherit;
}
</style>
<script setup lang="ts"> <script setup lang="ts">
const { params } = useRoute(); const { params } = useRoute();

191
src/pages/todos.vue

@ -1,18 +1,185 @@
<template> <template>
<TodoBrowse /> <ExampleComponent>
<br> <template v-slot:namedslot>
<TodoAdd /> <h1>named slot</h1>
<br>
<Button @click="showToast()" type="button">Toast</Button>
</template> </template>
default slot goes here
</ExampleComponent>
<script setup lang="ts"> <ExampleComponent>
import { useToast } from "primevue/usetoast"; <template #namedslot>
<h1>named slot</h1>
</template>
default slot goes here
</ExampleComponent>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris eget
nibh eget mi interdum porta eu at eros. Integer nec magna ligula.
Nulla turpis turpis, vulputate in gravida ac, euismod ullamcorper
mi. Pellentesque ornare leo lorem, eu mollis nisi congue feugiat.
Vestibulum eget interdum sem, ut eleifend quam. Sed cursus consequat
ex, quis sodales nunc gravida faucibus. Fusce et velit sed turpis
accumsan interdum sed ut enim. Suspendisse vehicula mi ac tellus
fermentum feugiat. Nullam volutpat tempor nunc, ac tincidunt nisi.
Sed varius est a nisi lobortis, vel gravida dui efficitur. Vivamus
in ipsum quis mi bibendum venenatis ac sed erat. Pellentesque id
ligula sapien. Vivamus elit mauris, volutpat eu venenatis ac,
condimentum et velit. Morbi ullamcorper tellus non magna faucibus,
et molestie erat euismod.
Ut posuere libero sed finibus bibendum. Integer non est eu sapien
gravida fringilla. Aliquam lobortis, ipsum in volutpat ullamcorper,
nunc augue consequat risus, id ultrices diam erat eu enim. Cras at
nibh turpis. Donec facilisis massa ante, et volutpat ante faucibus
nec. Nullam at dictum erat, eu iaculis nibh. Integer ac velit eget
dolor consequat tristique. Praesent interdum nisi eget libero
euismod congue ac vitae mi. Aliquam in ex quam. Sed id nisi in diam
lacinia dignissim a dapibus magna. Vivamus vestibulum suscipit
sapien. Aenean luctus orci at hendrerit rhoncus. Nam nec ligula nec
justo pellentesque finibus vitae id elit.
Cras posuere neque at pharetra lacinia. Etiam id suscipit dolor,
quis ullamcorper diam. Donec semper feugiat risus, sit amet maximus
risus lacinia in. Aenean auctor iaculis dui, et commodo ex
consectetur ac. Morbi elementum, est eget condimentum placerat,
sapien felis molestie neque, cursus tempus purus lectus at eros. Nam
in lorem eu magna elementum viverra ut nec lorem. Fusce auctor arcu
sodales nibh iaculis ultrices. Nunc mi elit, pulvinar ut quam eu,
iaculis gravida mauris. Sed ultrices, orci vitae pretium
condimentum, felis dolor auctor velit, vel viverra nulla lacus vel
lectus. Cras eros turpis, dignissim sit amet rutrum gravida,
placerat non nulla.
Curabitur at sodales lectus, vulputate accumsan tortor. Duis in
efficitur ex. Mauris imperdiet nibh urna, eu elementum erat
elementum a. Curabitur id magna ac risus euismod aliquet. Nullam
hendrerit gravida nisl, ac sodales nibh tempor mattis. Orci varius
natoque penatibus et magnis dis parturient montes, nascetur
ridiculus mus. Aenean viverra semper sapien. Nulla finibus nec metus
id molestie. Proin scelerisque venenatis enim, et maximus velit
imperdiet vel. Vestibulum sit amet nisi vel justo pharetra efficitur
sit amet ac elit. Donec feugiat id ante sit amet fermentum.
Pellentesque rhoncus ultricies erat, sit amet ultrices magna
condimentum ut. Donec vulputate efficitur augue a placerat.
Integer pulvinar erat ut ipsum ultrices, in posuere urna rhoncus.
Sed vestibulum nisl a magna volutpat, quis sodales leo vehicula.
Morbi tincidunt urna sed nisl feugiat, vel commodo nulla tincidunt.
Cras gravida massa et rutrum imperdiet. Proin eget iaculis urna. In
hac habitasse platea dictumst. Nullam consectetur ante sit amet
tortor ornare porttitor. Duis quis eros lorem. Morbi pulvinar
elementum purus, eget eleifend felis eleifend luctus. Sed iaculis
feugiat ligula, a hendrerit dui aliquet at. Aliquam erat volutpat.
Suspendisse id volutpat nisl, id iaculis ex. Morbi vehicula tellus a
arcu efficitur, et vehicula lectus vestibulum. Praesent sed
imperdiet dolor.
Nunc condimentum odio nec placerat auctor. Nam posuere condimentum
velit quis porttitor. Phasellus vitae enim et ex sodales lobortis
vel quis sapien. Maecenas at venenatis ante, sit amet elementum
risus. In lorem magna, fringilla fermentum diam sit amet, imperdiet
sollicitudin dui. Quisque eros magna, auctor ac hendrerit venenatis,
porta a lacus. Donec neque ligula, euismod nec mauris et, varius
commodo dolor. Etiam pharetra libero massa, eu congue metus
venenatis et. Nullam eu efficitur ligula. Suspendisse at scelerisque
libero, nec consequat nisl. In dignissim finibus nisl, volutpat
efficitur tellus scelerisque vitae. Phasellus quam mauris, bibendum
ac pretium nec, venenatis eget ipsum.
const toast = useToast(); Fusce eu risus porttitor eros venenatis ornare vel nec dui. Integer
feugiat non diam a molestie. Donec convallis turpis at orci
lobortis, id bibendum turpis posuere. Aenean quis lacus elementum,
condimentum elit ut, eleifend tortor. Ut dapibus ut nibh nec
pharetra. Suspendisse quis pulvinar tortor, in congue sapien. In hac
habitasse platea dictumst. Pellentesque tincidunt blandit tellus, in
mattis nulla luctus sit amet. Aliquam erat volutpat. Nunc elit
tortor, sagittis ut porta eleifend, congue quis orci. Nam a turpis
eu nulla sagittis ullamcorper eu vitae lectus. Vestibulum bibendum
vel mi vel gravida.
async function showToast() { Curabitur non maximus tortor. Aliquam ac est et enim vestibulum
toast.add({ severity: "success", summary: "This is a toast", detail: "Wow!", life: 3000 }); cursus ut et magna. Class aptent taciti sociosqu ad litora torquent
} per conubia nostra, per inceptos himenaeos. Sed nec nulla non ex
fringilla fringilla. Praesent accumsan eros tellus, ac venenatis
eros maximus in. Etiam ipsum felis, congue ut risus in, feugiat
ornare ante. Aliquam sed fringilla lectus. Aenean semper, odio vel
ultricies laoreet, est erat faucibus mi, sit amet tincidunt nunc dui
sit amet arcu. Proin feugiat augue diam, sed rutrum dui congue ac.
Nullam laoreet neque nunc, sed volutpat justo maximus ac. Sed eu
turpis aliquam, laoreet orci vitae, dictum ipsum. Quisque at
placerat orci. Suspendisse vulputate, erat eget pretium placerat,
metus magna consectetur metus, id rutrum neque est sed turpis. Nulla
pretium et lacus vel cursus.
</script> Maecenas quis libero mollis, commodo mi id, placerat nisl. Sed a
neque vel dui faucibus semper. Duis ullamcorper, libero at porta
convallis, lectus odio malesuada nunc, a tempus turpis ipsum at ex.
Nullam enim leo, hendrerit a quam vel, finibus auctor dui. Mauris
quis sem in nulla ornare pharetra vitae ut augue. Vivamus quis
tincidunt tortor, at imperdiet augue. Mauris augue augue, varius
vitae sapien et, efficitur rhoncus mi. Orci varius natoque penatibus
et magnis dis parturient montes, nascetur ridiculus mus. Cras ac
enim at est molestie elementum.
Duis viverra quam ut nibh sodales accumsan. In hac habitasse platea
dictumst. Sed a eros id elit malesuada ultrices. Quisque et diam
justo. Pellentesque eu placerat ante, sit amet sagittis sapien. Nam
sed sollicitudin urna. Proin non libero ut metus eleifend tempus.
Sed in augue ligula. Suspendisse potenti. In eu fermentum augue.
Aliquam sem ex, congue a condimentum ac, maximus a est. Integer in
dui non lectus molestie auctor. Nullam mollis pellentesque semper.
Etiam id neque facilisis, tristique sem et, porttitor purus.
Praesent aliquam, nisi vel porttitor blandit, risus felis lobortis
arcu, eu porttitor orci enim nec tortor. Maecenas id ante eget nisl
pulvinar feugiat ac vel ante.
Nam porttitor eleifend nisl. Vivamus ac aliquam lacus. Suspendisse
facilisis arcu vel consectetur efficitur. Fusce sodales mollis
auctor. Aenean nec sem a elit lobortis maximus tincidunt ac lorem.
Proin dolor quam, volutpat id aliquet eu, faucibus ut urna. Quisque
orci eros, blandit ut consequat vitae, convallis egestas libero.
Nunc interdum elit id dui congue consequat. Maecenas volutpat odio
diam. In tincidunt efficitur ultrices. Orci varius natoque penatibus
et magnis dis parturient montes, nascetur ridiculus mus. Mauris eget
faucibus leo. Cras rhoncus accumsan ante nec tempor. Class aptent
taciti sociosqu ad litora torquent per conubia nostra, per inceptos
himenaeos.
Cras sit amet blandit mi. Cras ac mi pulvinar, aliquet ex quis,
mollis nisi. Duis a interdum libero. Vivamus sit amet felis in ante
cursus gravida eget quis lectus. Praesent vehicula tortor accumsan
lectus pellentesque, in facilisis nisi fermentum. Mauris faucibus
vulputate sapien non semper. Vestibulum tristique interdum dolor, id
accumsan dolor malesuada et. Donec a porta augue.
Nunc eu urna quis nulla consequat sagittis. Nullam eleifend
tincidunt sapien in mattis. Praesent faucibus nibh at tortor
malesuada, ut lobortis nisi pulvinar. Morbi congue ullamcorper
ipsum, nec accumsan est imperdiet eu. Aenean sit amet finibus erat,
quis porta felis. Sed sollicitudin erat nec consequat faucibus. Nam
eleifend rutrum orci at commodo. Quisque est mi, gravida ut ultrices
sit amet, hendrerit quis velit. Aenean dignissim consequat magna,
non ornare lectus facilisis eu.
Maecenas vel risus fringilla, fermentum lacus vel, laoreet leo. Sed
ultricies, odio id ullamcorper consectetur, elit massa maximus
ligula, vitae lacinia libero est sed justo. Integer eget lectus eu
augue iaculis egestas. Nullam feugiat nisl metus, quis mollis dolor
suscipit at. Nulla ac nulla ultricies, fermentum turpis sit amet,
aliquam augue. Nulla quis vulputate nisi. Morbi dolor lectus,
lacinia vitae leo id, fringilla porttitor sapien.
Donec vestibulum, est sit amet auctor vestibulum, eros orci iaculis
lacus, a efficitur lectus odio non mi. Nullam cursus purus vitae
ante cursus, sed pulvinar magna condimentum. Suspendisse dignissim
lorem non lacus cursus, quis lacinia eros semper. Integer aliquam
felis iaculis sollicitudin vestibulum. Pellentesque ornare mi quam,
ac pellentesque mi molestie vel. Mauris vel sapien ultricies mauris
hendrerit vestibulum in at ligula. Morbi id velit vitae libero
molestie elementum. Vivamus maximus orci vel ante sodales, ut
pharetra erat egestas. Vivamus lacinia congue purus, nec volutpat
felis pulvinar egestas. Nam blandit venenatis aliquam. Nullam a
lorem et est sollicitudin pretium sed eget ex. Vivamus a quam est.
Aliquam tristique volutpat magna, aliquet volutpat lorem fermentum
sagittis.
</template>

6
tsconfig.json

@ -1,4 +1,8 @@
{ {
// https://nuxt.com/docs/guide/concepts/typescript // https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json" "extends": "./.nuxt/tsconfig.json",
"include": ["components.d.ts"],
"compilerOptions": {
"types": ["unplugin-icons/types/vue"]
}
} }

Loading…
Cancel
Save