Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
khanzadimahdi committed Aug 15, 2024
1 parent 75c2cd9 commit e31491e
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 184 deletions.
68 changes: 68 additions & 0 deletions frontend/components/comments/create.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<template>
<form class="my-3 py-1 d-flex flex-column" :class="{'mt-0': props.isReplying, 'child': props.isReplying}" @submit.prevent="createComment()">
<textarea :disabled="params.pending" v-model.trim="params.body" class="form-control mb-1" placeholder="دیدگاه خود را اینجا بنویسید" rows="3" required></textarea>
<span class="error text-danger" v-if="params.error">متن پیام باید بیشتر باشد.</span>
<div class="d-flex gap-2">
<button :disabled="params.pending" :class="{'btn-sm': props.isReplying}" type="submit" class="btn btn-success align-self-start my-1">
<span v-if="!params.pending">ثبت دیدگاه</span>
<div v-else class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</button>
</div>
</form>
</template>

<script setup lang="ts">
const emit = defineEmits(['commentCreated'])
const props = defineProps({
objectType: {
type: String,
required: true
},
objectUUID: {
type: String,
required: true
},
parentUUID: {
type: String,
default: "",
},
isReplying: {
type: Boolean,
default: false
}
})
const params = reactive({
pending: false,
error: false,
body: "",
})
async function createComment () {
const body = {
object_uuid: props.objectUUID,
object_type: props.objectType,
parent_uuid: props.parentUUID,
body: params.body,
}
try {
params.pending = true;
const data = await useUser().$fetch(useApiUrlResolver().resolve('api/comments'), {
method: 'POST',
headers: {authorization: `Bearer ${useAuth().accessToken()}`},
body: body,
})
emit('commentCreated', data)
params.body=""
} catch (e) {
params.error = true;
console.log(e)
}
params.pending = false;
}
</script>
67 changes: 31 additions & 36 deletions frontend/components/comments/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,46 @@
<span class="fa-regular fa-comment"></span>
<span class="mx-1">دیدگاه ها</span>
</h5>
<comments-write-new :disabled="disabled"
@sendComment="sendComment" v-if="params.isLogin"/>

<template v-if="useAuth().isLogin()">
<comments-create :objectType="props.objectType" :objectUUID="props.objectUUID"/>
</template>

<div v-else class="alert alert-light">
<i class="fa-regular fa-bell fa-shake fa-xl"></i>
<span class="mx-1">برای ثبت دیدگاه خود</span>
<NuxtLink class="mx-1" href="/auth/register">ثبت نام کنید</NuxtLink>
<span>یا</span>
<NuxtLink class="mx-1" to="/auth/login">وارد شوید</NuxtLink>
</div>
<comments-item v-for="(item , index) in comments" :key="index" :data="item" v-if="comments && comments.length"/>

<template v-if="comments && comments.length">
<comments-item v-for="(item , index) in comments" :key="index" :objectType="props.objectType" :objectUUID="props.objectUUID" :data="item"/>
</template>
</section>
</template>

<script lang="ts" setup>
const route = useRoute()
const {data} = defineProps(['data'])
useState('clearDataAfterCloseComment', ()=>false)
const comments = (data && data.length) ? createTree(data) : ""
const disabled = ref()
<script setup lang="ts">
const props = defineProps({
objectType: {
type: String,
required: true
},
objectUUID: {
type: String,
required: true
},
})
const data = await $fetch( useApiUrlResolver().resolve('api/comments'), {
query: {
object_type: props.objectType,
object_uuid: props.objectUUID,
page: 1
}
})
const comments = (data.items && data.items.length) ? createTree(data.items) : []
function createTree(comments: []): [] {
const map = new Map();
Expand All @@ -34,7 +55,7 @@ function createTree(comments: []): [] {
tree.push(comment);
}
});
// تکمیل کردن زیرمجموعه‌ها
tree.forEach((node: object) => {
const fillSubtree = (node: object) => {
node.sub = comments.filter(comment => comment.parent_uuid === node.uuid);
Expand All @@ -44,30 +65,4 @@ function createTree(comments: []): [] {
});
return tree;
}
const sendComment = async (text: string) => {
const body = {
object_uuid: route.params.uuid,
body: text,
object_type: 'article',
parent_uuid: ""
}
try {
disabled.value = true /* برای غیر فعال شدن دکمه ارسال کامنت بعد فشرده شدن تا زمان برشگت درخواست */
useState('clearDataAfterCloseComment').value = false /* برای خالی کردن مقدار کامنت در صورت موفقیت بودن درخواست */
const data = await useUser().$fetch(useApiUrlResolver().resolve('api/comments'), {
method: 'POST',
headers: {authorization: `Bearer ${useAuth().accessToken()}`},
body: JSON.stringify(body),
})
useState('clearDataAfterCloseComment').value = true
} catch (e) {
console.log(e)
} finally {
disabled.value = false /*جواب درخواست ما هرچی که باشه درانتها هر چی که باشه دکمه از حالت disable در میاد*/
}
}
const params = reactive({
isLogin: useAuth().isLogin(),
})
</script>
100 changes: 35 additions & 65 deletions frontend/components/comments/item.vue
Original file line number Diff line number Diff line change
@@ -1,98 +1,68 @@
<template>
<section :class="{child:child }" v-if="data">
<section :class="{child: props.data.parent_uuid}" v-if="data">
<section class="card mb-3">
<div class="card-body d-flex flex-start">
<img v-if="data.author.avatar" class="rounded-circle shadow-1-strong ms-3"
:src="useFilesUrlResolver().resolve(data.author.avatar)" alt="avatar" width="65"
height="65">
<img v-if="props.data.author.avatar" class="rounded-circle shadow-1-strong ms-3" :src="useFilesUrlResolver().resolve(props.data.author.avatar)" alt="avatar" width="65" height="65">
<div class="flex-grow-1 flex-shrink-1 ">
<div class="d-flex justify-content-between align-items-center">
<p class="info mb-1">
<span v-if="data.author.name">{{ data.author.name }}</span>
<span class="text-muted small me-1" v-if="data.created_at && data.created_at.length">
<span v-if="props.data.author.name">{{ props.data.author.name }}</span>
<span class="text-muted small me-1" v-if="props.data.created_at && props.data.created_at.length">
<span class="fa-regular fa-clock mx-1"></span>
<time datetime="">{{ useTime().toAgo(data.created_at) }}</time>
</span>
<time datetime="">{{ useTime().toAgo(props.data.created_at) }}</time>
</span>
</p>
<div v-if="params.isLogin" class="text-nowrap">
<div v-if="useAuth().isLogin()" class="text-nowrap">
<button class="btn text-danger btn-sm" v-if="false">
<i class="fas fa-trash fa-xs"></i>
</button>
<span v-if="false">|</span>
<button class="btn btn-sm" @click="showWriteComment">
<button class="btn btn-sm" @click.prevent="toggleShowCommentCreation">
<i class="fas fa-reply fa-xs"></i>
</button>
</div>
</div>
<p v-if="data.body && data.body.length" class="text small mb-0 pt-2 border-top ">{{ data.body }}</p>
<p v-if="props.data.body && props.data.body.length" class="text small mb-0 pt-2 border-top ">{{ props.data.body }}</p>
</div>
</div>
</section>
<section class="write-comment px-1" ref="writeComment">
<comments-write-new :clear-data="clearDataAfterCloseComment" :disabled="disabled" :parentInfo="data.uuid"
@send-comment="sendComment" :replyTheme="true">
<button class="btn btn-sm btn-md-lg btn-danger align-self-start mt-2" @click.prevent="showWriteComment">بستن
</button>
</comments-write-new>
<section class="write-comment px-1" ref="createCommentContainer">
<comments-create @commentCreated="toggleShowCommentCreation" :objectType="props.objectType" :objectUUID="props.objectUUID" :parentUUID="props.data.uuid" :isReplying="true" />
</section>
<comments-item v-if="data.sub && data.sub.length" v-for="(item , index) in data.sub" :key="index" :data="item"
:child="true"/>
<template v-if="props.data.sub && props.data.sub.length">
<comments-item v-for="(item , index) in props.data.sub" :key="index" :objectType="props.objectType" :objectUUID="props.objectUUID" :data="item"/>
</template>
</section>
</template>

<script setup lang="ts">
const {uuid} = useRoute().params
import {useFilesUrlResolver} from "~/composables/urlResolver";
const disabled = ref()
const writeComment = ref(null)
const clearDataAfterCloseComment = ref(false)
const {data, child} = defineProps({
const props = defineProps({
objectType: {
type: String,
required: true
},
objectUUID: {
type: String,
required: true
},
data: {
type: Object,
},
child: {
type: Boolean
}
})
/* در فانکشن زیر ما برای ظاهر شدن کامپوننت کامنت از maxHeight استفاده کردیم
به این صورت که در ابتدا صفر و با کلیک برروی ریپلای به اندازه طول
اسکرول آن بعلاوه 20 پیکسل بیشتر که ارفاع ارور آن دررمان ظاهر شدن است */
const showWriteComment = () => {
if (writeComment.value.style.maxHeight) {
writeComment.value.style.maxHeight = null
useState('clearDataAfterCloseComment').value = true
} else {
writeComment.value.style.maxHeight = writeComment.value.scrollHeight + 'px'
useState('clearDataAfterCloseComment').value = false
}
}
const sendComment = async (text: string, parentUuid: string) => {
const body = {
body: text,
object_type: 'article',
parent_uuid: parentUuid,
object_uuid: uuid
}
try {
disabled.value = true /* برای غیر فعال شدن دکمه ارسال کامنت بعد فشرده شدن تا زمان برشگت درخواست */
const data = await useUser().$fetch(useApiUrlResolver().resolve('api/comments'), {
method: 'POST',
headers: {authorization: `Bearer ${useAuth().accessToken()}`},
body: JSON.stringify(body)
})
showWriteComment() /*برای بسته شدن ریپلای در صورت موفقیت آمیز بودن ارسال درخواست */
} catch (e) {
console.log(e)
} finally {
disabled.value = false /* عملیات ارسال دیتا در نهایت هرچی که باشه دکمه ما تغیر حالت میده */
const createCommentContainer = ref()
function toggleShowCommentCreation() {
const element = createCommentContainer.value
if (element.style.maxHeight) {
element.style.maxHeight = null
return
}
}
const params = reactive({
isLogin: useAuth().isLogin(),
})
element.style.maxHeight = element.scrollHeight + 'px'
element.querySelector("textarea").focus()
}
</script>

<style scoped lang="scss">
Expand Down Expand Up @@ -135,7 +105,7 @@ p {
@keyframes reply {
0% {
transform: translateY(-10%);
opacity: -1;
opacity: 0;
}
100% {
transform: translateY(0);
Expand Down
52 changes: 0 additions & 52 deletions frontend/components/comments/writeNew.vue

This file was deleted.

Loading

0 comments on commit e31491e

Please sign in to comment.