This commit is contained in:
mohadese namavar
2024-06-16 00:22:14 +04:30
commit ec84dfd222
322 changed files with 77942 additions and 0 deletions
+53
View File
@@ -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>
+26
View File
@@ -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>
+71
View File
@@ -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>
+67
View File
@@ -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>
+63
View File
@@ -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>
+124
View File
@@ -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>
+28
View File
@@ -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>
+47
View File
@@ -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>
+74
View File
@@ -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>
+42
View File
@@ -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>