init git
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<aside class="blog-aside">
|
||||
<div v-for="(items, key) in list" :key="key">
|
||||
<h2>{{ $t(key) }}</h2>
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="(item, i) in items" :key="i">
|
||||
<BlogItem :data="item" type="small" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<BlogBanners />
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { lastBlog, topBlog } = inject('data')
|
||||
const list = reactive({ lastBlog, topBlog })
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog-aside {
|
||||
@apply max-w-full flex flex-col gap-6 lg:gap-12;
|
||||
@apply min-[1725px]:flex-col mx-auto;
|
||||
|
||||
&>div {
|
||||
@apply w-full flex overflow-hidden flex-col gap-6 lg:gap-12;
|
||||
|
||||
h2 {
|
||||
@apply flex items-center gap-3 text-[#333333] font-bold font-vazir leading-tight;
|
||||
@apply text-base lg:text-2xl px-6 lg:px-0;
|
||||
|
||||
&::after {
|
||||
@apply content-['_'] grow h-px bg-[#E5E5E5] lg:hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&>div {
|
||||
@apply overflow-x-auto max-w-[100vw] py-px scroll-smooth grow-0;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply flex lg:flex-col w-max gap-[1.1rem] lg:gap-6 px-6 lg:px-0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<ul v-if="banners">
|
||||
<li v-for="({ link, src }, i) in banners" :key="i">
|
||||
<router-link :to="link">
|
||||
<img :src="src" />
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { banners = [] } = inject('data')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog>aside>ul {
|
||||
@apply flex-col gap-10 justify-end hidden lg:flex;
|
||||
@apply gap-5 sm:gap-6 md:gap-7 lg:gap-8 xl:gap-9 2xl:gap-10;
|
||||
|
||||
li {
|
||||
img {
|
||||
@apply w-full max-w-[26.1rem] bg-zinc-300 rounded-[0.6rem] overflow-hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<article class="post-card">
|
||||
<img :src="data.coverImage" />
|
||||
<div>
|
||||
<small>
|
||||
<router-link :to="{ path: '/blog', query: data.category.link }">
|
||||
{{ data.category.title }}
|
||||
</router-link>
|
||||
</small>
|
||||
<h1>
|
||||
<router-link :to="'/blog/' + data.link">
|
||||
{{ data.title }}
|
||||
</router-link>
|
||||
</h1>
|
||||
<p v-html="data.content"></p>
|
||||
<div>
|
||||
<span>{{ new Date(data.createdAt).toLocaleDateString('fa') }}</span>
|
||||
<router-link :to="'/blog/' + data.link">
|
||||
<Button :label="$t('readMore')" icon="isax isax-arrow-left" severity="secondary" text />
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({ data: { type: Object, default: {} } })
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.post-card {
|
||||
box-shadow: 0px 1px 22px 0px rgba(0, 75, 130, 0.15);
|
||||
@apply w-[21.3rem] h-[23.3rem] lg:w-[18.3rem] lg:h-[24.3rem] bg-white rounded-2xl p-3 flex flex-col gap-3;
|
||||
|
||||
img {
|
||||
@apply w-full h-[10.4rem] bg-[#ECECEC] rounded-xl;
|
||||
}
|
||||
|
||||
&>div {
|
||||
@apply flex flex-col px-3 grow;
|
||||
|
||||
small {
|
||||
@apply text-primary-600 text-xs lg:text-sm font-vazir;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@apply text-[#191919] font-bold font-vazir mt-1.5 text-sm lg:text-base;
|
||||
}
|
||||
|
||||
&>p {
|
||||
@apply text-[#7F7F7F] font-vazir mt-2 w-[14.4rem] text-xs leading-5 lg:text-sm lg:leading-[1.4rem] line-clamp-3;
|
||||
}
|
||||
|
||||
div {
|
||||
@apply flex items-center justify-between mt-auto;
|
||||
|
||||
span {
|
||||
@apply text-[#7F7F7F] text-xs lg:text-sm font-normal font-vazir leading-snug;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply whitespace-nowrap h-10 -ml-3 px-2 text-xs lg:text-sm #{!important};
|
||||
|
||||
.isax {
|
||||
@apply text-xl #{!important};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<details class="blog-categories" open>
|
||||
<summary>
|
||||
<h2>{{ $t('categoryOfContent') }}</h2>
|
||||
<i class="isax isax-arrow-circle-down"></i>
|
||||
</summary>
|
||||
<ul>
|
||||
<li v-for="(category, i) in blogCategory" :key="i">
|
||||
<router-link :to="{ path: '/blog', query: { category: category.link } }">
|
||||
<span>{{ category.name }}</span>
|
||||
<i :class="{ selected: category.link == selectedCate }"></i>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps(['data'])
|
||||
const { blogCategory, selectedCate } = inject('data') || props.data
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog-categories {
|
||||
@apply w-[17.1rem] lg:w-[18.3rem] appearance-none select-none shrink-0 rtl max-xl:hidden;
|
||||
@apply h-full bg-white m-0 max-h-none ml-auto 2xl:ml-6 #{!important};
|
||||
|
||||
summary {
|
||||
@apply w-full h-[3.9rem] lg:h-[5.5rem] flex items-center justify-between bg-[#43E97B] lg:rounded-[0.6rem] p-4 cursor-pointer;
|
||||
|
||||
h2 {
|
||||
@apply text-stone-50 text-lg lg:text-xl font-bold font-vazir leading-[2.8rem];
|
||||
}
|
||||
|
||||
i {
|
||||
@apply text-white text-[1.4em] lg:text-2xl transition-transform;
|
||||
}
|
||||
}
|
||||
|
||||
&[open] summary i {
|
||||
@apply rotate-180;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply flex flex-col gap-3 mt-[1.1rem] lg:gap-4 lg:mt-4 px-3 lg:px-0;
|
||||
|
||||
li {
|
||||
a {
|
||||
@apply w-full h-14 bg-[#F8F8F8] rounded-[0.6rem];
|
||||
@apply flex items-center justify-between px-[1.1rem] lg:p-4 hover:bg-stone-100;
|
||||
|
||||
span {
|
||||
@apply text-neutral-400 text-sm lg:text-xl font-medium font-vazir leading-[1.9rem];
|
||||
}
|
||||
|
||||
i {
|
||||
@apply w-2.5 h-2.5 lg:w-3 lg:h-3 bg-[#D9D9D9] rounded-full;
|
||||
}
|
||||
|
||||
.selected {
|
||||
@apply bg-[#43E97B];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<article>
|
||||
<router-link :to="'/blog?category=' + category.link">
|
||||
{{ category.name }}
|
||||
</router-link>
|
||||
<h1>{{ title }}</h1>
|
||||
<span>{{ $t('author') }}: {{ userID.firstName }} {{ userID.lastName }}</span>
|
||||
<div>
|
||||
<i class="isax isax-calendar-1"></i>
|
||||
<span>{{ new Date(createdAt).toLocaleString('fa') }}</span>
|
||||
</div>
|
||||
<img :src="coverImage" :alt="title" />
|
||||
<div v-html="content" />
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const data = inject('data')
|
||||
const { category, userID, createdAt, coverImage, title, content } = data.post
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog-post>section>article {
|
||||
@apply w-full max-lg:container max-w-[64.6rem] flex flex-col max-lg:px-6;
|
||||
|
||||
&>a {
|
||||
@apply text-primary-600 font-vazir w-max hover:underline;
|
||||
@apply text-xs lg:text-2xl lg:leading-[2.7rem] mt-3 lg:mt-0;
|
||||
}
|
||||
|
||||
&>h1 {
|
||||
@apply text-[#404040] font-bold font-vazir;
|
||||
@apply text-base lg:text-3xl mt-2 lg:mt-6;
|
||||
}
|
||||
|
||||
&>span {
|
||||
@apply text-[#BFBFBF] font-normal font-vazir;
|
||||
@apply text-sm lg:text-xl lg:leading-9 mt-[1.1rem] lg:mt-8;
|
||||
}
|
||||
|
||||
&>div:first-of-type {
|
||||
@apply flex items-center gap-1.5 lg:gap-2 text-[#BFBFBF] mt-2;
|
||||
|
||||
&>span {
|
||||
@apply font-normal font-vazir;
|
||||
@apply text-sm lg:text-xl;
|
||||
}
|
||||
|
||||
i {
|
||||
@apply text-[1.4em] lg:text-2xl;
|
||||
}
|
||||
}
|
||||
|
||||
&>img {
|
||||
@apply w-full bg-zinc-300 order-first lg:order-none lg:mt-6;
|
||||
}
|
||||
|
||||
&>div:last-of-type {
|
||||
@apply text-[#595959] font-vazir mt-9 lg:mt-12 text-justify;
|
||||
@apply text-sm leading-6 lg:text-xl lg:leading-9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<router-link :to="'/blog/' + link" :class="['post-item', `post-item-${type}`]">
|
||||
<article>
|
||||
<img :src="coverImage" :alt="title" />
|
||||
<div>
|
||||
<h1>{{ title }}</h1>
|
||||
<div v-if="type != 'vertical'" v-html="content" />
|
||||
<Button v-if="type == 'normal'" v-bind="btn.props" />
|
||||
</div>
|
||||
</article>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import init from '../../initialize/post-item'
|
||||
const { btn } = init()
|
||||
|
||||
const props = defineProps({
|
||||
type: { default: 'normal' },
|
||||
data: {},
|
||||
});
|
||||
|
||||
const { link, coverImage, title, content } = props.data
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.post-item {
|
||||
article {
|
||||
@apply flex gap-3 lg:gap-6;
|
||||
|
||||
img {
|
||||
@apply object-contain object-center;
|
||||
}
|
||||
|
||||
&>div {
|
||||
@apply flex flex-col overflow-hidden font-vazir;
|
||||
|
||||
h1 {
|
||||
@apply text-zinc-800 font-bold truncate;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply text-zinc-500 lg:leading-[1.9rem];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-item-normal {
|
||||
article {
|
||||
@apply w-[21.4rem] h-[4.7rem];
|
||||
@apply lg:w-[55.9rem] lg:h-[11.9rem];
|
||||
|
||||
img {
|
||||
@apply w-[4.7rem] h-[4.7rem] lg:w-[15.1rem] lg:h-[11.9rem] object-cover;
|
||||
}
|
||||
|
||||
&>div {
|
||||
@apply flex flex-col justify-between lg:justify-center;
|
||||
@apply gap-1 lg:gap-6;
|
||||
|
||||
h1 {
|
||||
@apply text-xs lg:text-2xl whitespace-normal;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply hidden lg:block w-[39.4rem] line-clamp-3;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply w-max h-max text-[#43E97B] py-1.5 px-3.5 -mr-3.5 -my-1.5 #{!important};
|
||||
|
||||
.p-button-label {
|
||||
@apply font-normal font-vazir text-[0.7em] lg:text-base;
|
||||
}
|
||||
|
||||
.isax {
|
||||
@apply text-base lg:text-2xl mr-1 #{!important};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-item-small {
|
||||
article {
|
||||
@apply w-[21.4rem] h-[4.7rem] lg:w-[26.1rem] lg:h-[7.7rem];
|
||||
|
||||
img {
|
||||
@apply w-[4.8rem] h-[4.8rem] lg:w-[7.7rem] lg:h-[7.7rem];
|
||||
}
|
||||
|
||||
&>div {
|
||||
@apply gap-2 lg:gap-0.5 justify-center;
|
||||
|
||||
h1 {
|
||||
@apply text-xs lg:text-base lg:leading-[2.8rem];
|
||||
}
|
||||
|
||||
p {
|
||||
@apply text-[0.7em] lg:text-base lg:w-[16.9rem] line-clamp-2;
|
||||
}
|
||||
|
||||
button {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-item-vertical {
|
||||
article {
|
||||
@apply flex-col gap-3 lg:gap-4 w-[9.9rem] lg:w-[18.3rem];
|
||||
|
||||
img {
|
||||
@apply w-full h-[9.9rem] lg:h-[18.3rem] object-cover;
|
||||
}
|
||||
|
||||
&>div h1 {
|
||||
@apply text-xs lg:text-base leading-6 line-clamp-3 lg:line-clamp-2 whitespace-break-spaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<section>
|
||||
<ul>
|
||||
<li v-for="(item, i) in blogs" :key="i">
|
||||
<BlogItem :data="item" />
|
||||
</li>
|
||||
</ul>
|
||||
<AppPagination :pages="pages" />
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { blogs, pages } = inject('data')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog>section {
|
||||
@apply flex flex-col justify-between px-4 lg:px-6 xl:px-0 w-full xl:w-auto items-center;
|
||||
|
||||
&>ul:not([class]) {
|
||||
@apply flex flex-col gap-6 max-lg:w-full;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
@apply self-center my-[1.9rem] lg:my-[7.4rem];
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<section v-if="relatedPosts.length > 0" class="blog-relateds">
|
||||
<div>
|
||||
<h2>{{ $t("relatedPosts") }}</h2>
|
||||
<Swiper slides-per-view="auto">
|
||||
<SwiperSlide v-for="(item, i) in relatedPosts" :key="i">
|
||||
<BlogItem :data="item" type="vertical" />
|
||||
</SwiperSlide>
|
||||
</Swiper>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { relatedPosts = [] } = inject('data')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog-relateds {
|
||||
@apply w-full flex justify-center;
|
||||
|
||||
&>div {
|
||||
@apply w-full flex flex-col gap-6 lg:gap-14;
|
||||
|
||||
h2 {
|
||||
@apply flex gap-3 lg:gap-6 items-center text-[#333333] font-bold font-vazir;
|
||||
@apply text-base lg:text-2xl lg:leading-[1.9rem] px-6;
|
||||
|
||||
&::before {
|
||||
@apply content-['_'] w-1 h-[1.2rem] lg:h-6 lg:w-[0.3rem] rounded-full bg-primary-600;
|
||||
}
|
||||
}
|
||||
|
||||
.swiper {
|
||||
@apply container px-6;
|
||||
|
||||
.swiper-wrapper {
|
||||
@apply w-max;
|
||||
|
||||
.swiper-slide {
|
||||
@apply w-max ml-[1.1rem] lg:ml-6 last:ml-0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="blog-share">
|
||||
<i class="isax isax-hierarchy-2"></i>
|
||||
<h3>{{ $t("share") }}</h3>
|
||||
<ul>
|
||||
<li v-for="(item, i) in items" :key="i">
|
||||
<a :href="item.url" target="_blank">
|
||||
<img :src="`/icons/${item.icon}.svg`" />
|
||||
</a>
|
||||
</li>
|
||||
<li @click="copyToClipboard()">
|
||||
<i class="isax isax-link-21"></i>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { post: { title } } = inject('data')
|
||||
const { toast, t } = inject('service')
|
||||
const route = useRoute();
|
||||
const path = document.location.href;
|
||||
const items = reactive([
|
||||
{ icon: "linkedin", url: `https://www.linkedin.com/sharing/share-offsite/?title=${title}&url=${path}` },
|
||||
{ icon: "telegram", url: `https://t.me/share/url?text=${title}&url=${path}` },
|
||||
{ icon: "whatsapp", url: `https://api.whatsapp.com/send?text=${title} ${path}` },
|
||||
{ icon: "twitter", url: `http://twitter.com/share?text=${title}&url${path}` },
|
||||
]);
|
||||
const copyToClipboard = () => {
|
||||
toast.add({ life: 3000, severity: 'success', summary: t('success'), detail: t('copied') })
|
||||
navigator.clipboard.writeText(path)
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.blog-share {
|
||||
@apply w-auto lg:w-[26.8rem] lg:max-w-[26.8rem] flex items-center rounded-[0.6rem] relative max-lg:mx-6;
|
||||
@apply flex-col lg:flex-row lg:h-14 lg:overflow-hidden lg:bg-zinc-100 gap-4 lg:gap-0;
|
||||
|
||||
&>i {
|
||||
@apply text-2xl lg:hidden;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@apply bg-neutral-200 w-full sm:w-[9.3rem] h-10 sm:h-full text-zinc-900;
|
||||
@apply font-medium font-vazir leading-[1.9rem] items-center justify-center;
|
||||
@apply text-lg hidden lg:flex;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply w-[14.3rem] flex gap-6 justify-center items-center grow h-9 text-[#333333] relative;
|
||||
@apply bg-white rounded-[0.3rem] shadow-[0px_0px_10px_10px_#0000000a] z-[1];
|
||||
@apply lg:shadow-none lg:h-full lg:bg-[#F2F2F2];
|
||||
|
||||
li {
|
||||
img {
|
||||
@apply w-5 h-5 lg:w-6 lg:h-6 object-scale-down object-bottom brightness-[0.45];
|
||||
}
|
||||
|
||||
i {
|
||||
@apply text-xl lg:text-[1.6em] lg:leading-9 cursor-pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
@apply max-lg:content-['_'] w-4 h-4 transform rotate-45 bg-white absolute -top-2 rounded;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
@apply max-lg:content-['_'] absolute bottom-4 inset-x-0 h-0.5 bg-[#E5E5E5] z-0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="post-tags">
|
||||
<h3>{{ $t('tags') }}:</h3>
|
||||
<ul>
|
||||
<li v-for="(tag, i) in post.tags" :key="i">
|
||||
<router-link :to="`/blog?tag=${tag}`">
|
||||
<span>{{ tag }}</span>
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const { post } = inject('data')
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.post-tags {
|
||||
@apply flex items-center gap-3 lg:gap-4 px-6;
|
||||
|
||||
h3 {
|
||||
@apply text-zinc-900 font-medium font-vazir leading-[1.9rem] whitespace-nowrap;
|
||||
@apply text-xs lg:text-lg pt-1.5 lg:pt-0;
|
||||
}
|
||||
|
||||
ul {
|
||||
@apply flex flex-wrap items-center;
|
||||
@apply gap-1.5 lg:gap-4;
|
||||
|
||||
a {
|
||||
@apply bg-[#F2F2F2] rounded-[0.3rem] lg:rounded-[0.6rem] flex items-center justify-center;
|
||||
@apply px-4 h-7 lg:h-[2.4rem];
|
||||
|
||||
span {
|
||||
@apply text-[#333333] font-normal font-vazir leading-[1.9rem];
|
||||
@apply text-xs lg:text-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user