init
This commit is contained in:
86
src/components/Pagination.vue
Normal file
86
src/components/Pagination.vue
Normal file
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<ul class="flex pl-0 list-none rounded my-2">
|
||||
|
||||
<li class="w-10 relative block text-center py-2 leading-tight bg-white border border-gray-300 text-black ml-0 mr-1 rounded hover:bg-gray-300" v-if="!isFirstPage(currentPage, totalPages)">
|
||||
<g-link :to="previousPage(currentPage,totalPages)" class="page-link" tabindex="-1" >«</g-link>
|
||||
</li>
|
||||
|
||||
<li
|
||||
v-for="page in pages" :key="page.name"
|
||||
v-bind:class="[isCurrentPage(currentPage, page.name) ? 'border-l-2 border-l-black' : '']"
|
||||
class="w-10 relative block py-2 text-center leading-tight bg-white border border-gray-300 text-black rounded hover:bg-gray-300 ml-1 mr-1">
|
||||
<g-link
|
||||
:to="page.link"
|
||||
class="page-link"
|
||||
:aria-label="page.name"
|
||||
:aria-current="page.name"
|
||||
>{{page.name}}</g-link>
|
||||
</li>
|
||||
|
||||
<li class="w-10 relative block py-2 text-center leading-tight bg-white border border-gray-300 text-black ml-1 rounded hover:bg-gray-300" v-if="!isLastPage(currentPage, totalPages)">
|
||||
<g-link :to="nextPage(currentPage,totalPages)" class="page-link" tabindex="-1" >»</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
baseUrl: String,
|
||||
currentPage: Number,
|
||||
totalPages: Number,
|
||||
maxVisibleButtons: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 3
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isFirstPage(currentPage, totalPages) {
|
||||
return currentPage == 1;
|
||||
},
|
||||
isLastPage(currentPage, totalPages) {
|
||||
return currentPage == totalPages;
|
||||
},
|
||||
isCurrentPage(currentPage, pageElement) {
|
||||
return currentPage == pageElement;
|
||||
},
|
||||
nextPage(currentPage, totalPages) {
|
||||
return `${this.baseUrl}/${currentPage + 1}`;
|
||||
},
|
||||
previousPage(currentPage, totalPages) {
|
||||
return currentPage === 2
|
||||
? `${this.baseUrl}/`
|
||||
: `${this.baseUrl}/${currentPage - 1}`;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
startPage() {
|
||||
if (this.currentPage === 1) {
|
||||
return 1;
|
||||
}
|
||||
if (this.currentPage === this.totalPages) {
|
||||
return this.currentPage - 1;
|
||||
}
|
||||
return this.currentPage - 1;
|
||||
},
|
||||
pages() {
|
||||
const range = [];
|
||||
for (
|
||||
let i = this.startPage;
|
||||
i <=
|
||||
Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages);
|
||||
i += 1
|
||||
) {
|
||||
range.push({
|
||||
name: i,
|
||||
isDisabled: i === this.currentPage,
|
||||
link: i === 1 ? `${this.baseUrl}/` : `${this.baseUrl}/${i}`
|
||||
});
|
||||
}
|
||||
return range;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
62
src/components/PostListItem.vue
Normal file
62
src/components/PostListItem.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="flex flex-post px-0 sm:px-4 pb-8 mb-8" v-bind:class="{'no-border': !border}">
|
||||
<g-link :to="record.path" class="post-card-image-link">
|
||||
<g-image :src="record.image" :alt="record.title" class="post-card-image"></g-image>
|
||||
</g-link>
|
||||
<div class="post-card-content">
|
||||
<g-link :to="record.path">
|
||||
<p class="uppercase font-medium text-xs text-blue-700 mt-3">{{ record.category.title }}</p>
|
||||
<h2 class="post-card-title mt-0">
|
||||
{{ record.title }}
|
||||
</h2>
|
||||
<p class="post-card-excerpt">{{ record.excerpt }}</p>
|
||||
</g-link>
|
||||
<div class="w-full post-card-meta pt-4">
|
||||
<div class="avatars">
|
||||
<div class="flex items-center">
|
||||
<div class="flex justify-between items-center">
|
||||
<ul class="list-none flex author-list">
|
||||
<li v-for="author in record.author" :key="author.id" class="author-list-item">
|
||||
<g-link :to="author.path" v-tooltip="author.name">
|
||||
<g-image
|
||||
:src="author.image"
|
||||
:alt="author.name"
|
||||
class="w-8 h-8 rounded-full bg-gray-200 border-2 border-white"
|
||||
/>
|
||||
</g-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ml-3 pl-3 border-l flex flex-col text-xs leading-none uppercase">
|
||||
<p>
|
||||
<time :datetime="record.datetime" >{{ record.humanTime }}</time>
|
||||
</p>
|
||||
<time :datetime="record.datetime" >{{ record.startDate }}</time>
|
||||
{{ record.status }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
record: {},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
44
src/components/ThemeSwitcher.vue
Normal file
44
src/components/ThemeSwitcher.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<a role="button" @click.prevent="toggleTheme()"
|
||||
:aria-label="'Toggle ' + nextTheme"
|
||||
:title="'Toggle ' + nextTheme"
|
||||
class="toggle-theme"
|
||||
>
|
||||
|
||||
<font-awesome :icon="['fas', 'sun']" class="mr-3" v-if="theme === 'dark'"></font-awesome>
|
||||
<font-awesome :icon="['fas', 'moon']" class="mr-3" v-if="theme === 'light'"></font-awesome>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let themes = ['light', 'dark']
|
||||
|
||||
export default {
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
nextTheme() {
|
||||
const currentIndex = themes.indexOf(this.theme)
|
||||
const nextIndex = (currentIndex + 1) % themes.length
|
||||
return themes[nextIndex]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleTheme() {
|
||||
const currentIndex = themes.indexOf(this.theme);
|
||||
const nextIndex = (currentIndex + 1) % themes.length;
|
||||
window.__setPreferredTheme(themes[nextIndex])
|
||||
|
||||
this.$emit('setTheme', themes[nextIndex])
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
// set default
|
||||
if (typeof window.__theme !== 'undefined') this.$emit('setTheme', window.__theme)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
27
src/components/VacationCard.vue
Normal file
27
src/components/VacationCard.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div>
|
||||
<img class="rounded" :src="img" :alt="imgAlt">
|
||||
<div class="mt-2">
|
||||
<div>
|
||||
<div class="text-xs text-gray-600 uppercase font-bold">{{ eyebrow }}</div>
|
||||
<div class="font-bold text-gray-700 leading-snug">
|
||||
<a :href="url" class="hover:underline">{{ title }}</a>
|
||||
</div>
|
||||
<div class="mt-2 text-sm text-gray-600">{{ pricing }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- TODO: how do I get markdown in here? -->
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['img', 'imgAlt', 'eyebrow', 'title', 'pricing', 'url']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
Reference in New Issue
Block a user