Completion of APIs except for user progress
This commit is contained in:
@@ -3,21 +3,24 @@
|
|||||||
class="flex flex-col md:flex-row justify-between items-center py-[10vw] md:py-0 absolute top-[140vw] md:top-[54.3vw] w-full z-[3] border-y h-[133.846vw] md:h-[9.115vw] text-[#383E43] px-[10vw]"
|
class="flex flex-col md:flex-row justify-between items-center py-[10vw] md:py-0 absolute top-[140vw] md:top-[54.3vw] w-full z-[3] border-y h-[133.846vw] md:h-[9.115vw] text-[#383E43] px-[10vw]"
|
||||||
>
|
>
|
||||||
<div class="flexBox flex-col">
|
<div class="flexBox flex-col">
|
||||||
<p class="text-[8.318vw] md:text-[2.344vw]">280</p>
|
<p class="text-[8.318vw] md:text-[2.344vw]">{{info.data.value.expertise}}</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">حوزه تخصصی</p>
|
<p class="text-[3.59vw] md:text-[0.938vw]">حوزه تخصصی</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexBox flex-col">
|
<div class="flexBox flex-col">
|
||||||
<p class="text-[8.318vw] md:text-[2.344vw]">2,200,000</p>
|
<p class="text-[8.318vw] md:text-[2.344vw]">{{ numberFormat(info.data.value.student) }}</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">دانشجو</p>
|
<p class="text-[3.59vw] md:text-[0.938vw]">دانشجو</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexBox flex-col">
|
<div class="flexBox flex-col">
|
||||||
<p class="text-[8.318vw] md:text-[2.344vw]">8,100</p>
|
<p class="text-[8.318vw] md:text-[2.344vw]">{{ numberFormat(info.data.value.title) }}</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">عنوان آموزشی</p>
|
<p class="text-[3.59vw] md:text-[0.938vw]">عنوان آموزشی</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flexBox flex-col">
|
<div class="flexBox flex-col">
|
||||||
<p class="text-[8.318vw] md:text-[2.344vw]">27,000</p>
|
<p class="text-[8.318vw] md:text-[2.344vw]">{{ numberFormat(info.data.value.hours) }}</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">ساعت آموزش</p>
|
<p class="text-[3.59vw] md:text-[0.938vw]">ساعت آموزش</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
|
const info = await useFetch('/api/settings')
|
||||||
|
</script>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="text-[#383E43] font-semibold">
|
<div class="text-[#383E43] font-semibold">
|
||||||
<p class="text-[5.11vw] md:text-[1.979vw]">+2000</p>
|
<p class="text-[5.11vw] md:text-[1.979vw]">{{info.data.value.student}} +</p>
|
||||||
<p class="text-[3.59vw] md:text-[1.502vw]">دانشجو</p>
|
<p class="text-[3.59vw] md:text-[1.502vw]">دانشجو</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div class="text-[#383E43] font-semibold">
|
<div class="text-[#383E43] font-semibold">
|
||||||
<p class="text-[5.11vw] md:text-[1.979vw]">375</p>
|
<p class="text-[5.11vw] md:text-[1.979vw]">{{info.data.value.title}}</p>
|
||||||
<p class="text-[3.59vw] md:text-[1.502vw]">ویدئوی آموزشی</p>
|
<p class="text-[3.59vw] md:text-[1.502vw]">ویدئوی آموزشی</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -121,3 +121,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const info = await useFetch('/api/settings')
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -235,26 +235,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- comments -->
|
<!-- comments -->
|
||||||
|
|
||||||
<div class="flex items-center gap-[3vw] md:gap-[0.7vw] mt-[15vw] md:mt-[7vw]">
|
<div
|
||||||
|
class="flex items-center gap-[3vw] md:gap-[0.7vw] mt-[15vw] md:mt-[7vw]"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="w-[1.538vw] md:w-[0.521vw] h-[8.462vw] md:h-[2.76vw]"
|
class="w-[1.538vw] md:w-[0.521vw] h-[8.462vw] md:h-[2.76vw]"
|
||||||
viewBox="0 0 10 53"
|
viewBox="0 0 10 53"
|
||||||
@@ -266,19 +251,96 @@
|
|||||||
fill="#0D3F40"
|
fill="#0D3F40"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-[4.544vw] md:text-[1.481vw] font-semibold">پرسش و پاسخ</span>
|
<span class="text-[4.544vw] md:text-[1.481vw] font-semibold"
|
||||||
|
>پرسش و پاسخ</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-[#F8F8F8] p-[4vw] md:p-[1vw] rounded-[3.846vw] md:rounded-[0.781vw] mt-[6vw] md:mt-[2vw]">
|
<div
|
||||||
|
v-for="item in activeHead.Comment"
|
||||||
|
:key="item.id"
|
||||||
|
class="mt-[1vw] relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[4vw] md:p-[1.55vw]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-if="item.user?.avatarMedia"
|
||||||
|
:src="item.user?.avatarMedia"
|
||||||
|
alt="profile"
|
||||||
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
src="/public/images/alt.png"
|
||||||
|
alt="profile"
|
||||||
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="ps-[3vw] md:ps-[1vw] w-full">
|
||||||
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
|
{{ item.user.name ? item.user.name : "کاربر مهمان" }}
|
||||||
|
</p>
|
||||||
|
<div class="thin">
|
||||||
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
|
{{ jDate(item.createdAt) }}
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="w-[98%] text-[3.19vw] md:text-[0.833vw] text-[#383E43] leading-[4.785vw] md:leading-[1.25vw] mt-[2vw] md:mt-[0.5vw]"
|
||||||
|
>
|
||||||
|
{{ item.text }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
@click="reply(item.id)"
|
||||||
|
class="cursor-pointer absolute md:left-[2vw] left-[5vw] h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7.12988 18.3101H15.1299C17.8899 18.3101 20.1299 16.0701 20.1299 13.3101C20.1299 10.5501 17.8899 8.31006 15.1299 8.31006H4.12988"
|
||||||
|
stroke="#383E43"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-miterlimit="10"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M6.43012 10.8099L3.87012 8.24994L6.43012 5.68994"
|
||||||
|
stroke="#383E43"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="bg-[#F8F8F8] p-[4vw] md:p-[1vw] rounded-[3.846vw] md:rounded-[0.781vw] mt-[6vw] md:mt-[2vw]"
|
||||||
|
>
|
||||||
<div class="space-y-[5vw] md:space-y-[1vw]">
|
<div class="space-y-[5vw] md:space-y-[1vw]">
|
||||||
<div class="flex gap-[1vw]">
|
<div class="flex gap-[1vw]">
|
||||||
<img
|
<img
|
||||||
src="/public/images/client1.png"
|
v-if="authUser.avatarMedia"
|
||||||
|
:src="authUser.avatarMedia"
|
||||||
alt=""
|
alt=""
|
||||||
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
||||||
/>
|
/>
|
||||||
<div class="space-y-[4vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0">
|
<img
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">علی مصلحی</p>
|
v-else
|
||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">پرسش جدید</p>
|
src="/public/images/alt.png"
|
||||||
|
alt=""
|
||||||
|
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="space-y-[4vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0"
|
||||||
|
>
|
||||||
|
<p class="text-[3.59vw] md:text-[0.938vw]">
|
||||||
|
{{ authUser?.name ? authUser.name : "کاربر مهمان" }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
|
پرسش جدید
|
||||||
|
</p>
|
||||||
|
{{replyId}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -289,8 +351,11 @@
|
|||||||
cols="30"
|
cols="30"
|
||||||
rows="10"
|
rows="10"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="flex justify-end gap-[1vw] text-[3.19vw] md:text-[0.833vw] text-white">
|
<div
|
||||||
|
class="flex justify-end gap-[1vw] text-[3.19vw] md:text-[0.833vw] text-white"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
|
@click="replyId = null"
|
||||||
class="h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-[#5A6268]"
|
class="h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-[#5A6268]"
|
||||||
>
|
>
|
||||||
حذف
|
حذف
|
||||||
@@ -304,29 +369,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full md:w-[23.438vw]">
|
<div class="w-full md:w-[23.438vw]">
|
||||||
@@ -338,7 +380,7 @@
|
|||||||
<label
|
<label
|
||||||
v-for="item in data"
|
v-for="item in data"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
:class="{ 'bg-[#F4FDFD]': item === activeHead }"
|
|
||||||
class="cursor-pointer text-[#383E43] h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
class="cursor-pointer text-[#383E43] h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
||||||
>
|
>
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
||||||
@@ -404,8 +446,9 @@ const video = ref(null);
|
|||||||
const url = ref(null);
|
const url = ref(null);
|
||||||
const query = ref({});
|
const query = ref({});
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const comment = ref(null)
|
const comment = ref(null);
|
||||||
query.value = route.query;
|
query.value = route.query;
|
||||||
|
const { authUser } = useAuth();
|
||||||
const { data, refresh } = await useFetch("/api/courseHeadlines", {
|
const { data, refresh } = await useFetch("/api/courseHeadlines", {
|
||||||
query: {
|
query: {
|
||||||
id: route.params.product,
|
id: route.params.product,
|
||||||
@@ -414,27 +457,47 @@ const { data, refresh } = await useFetch("/api/courseHeadlines", {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const sendComment = async () => {
|
||||||
|
if (comment.value === "" || comment.value === null) {
|
||||||
|
return toast.error("متن خود را وارد کنید");
|
||||||
|
}
|
||||||
const sendComment = () => {
|
if (replyId.value === null) {
|
||||||
const comments = useFetch('/api/comments/courseHeadline',{
|
const commentss = await $fetch("/api/comments/courseHeadline", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
id: activeHead.value.id,
|
id: activeHead.value.id,
|
||||||
text: comment.value
|
text: comment.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
refresh();
|
||||||
|
toast.success("نظر شما با موفقیت ثبت شد");
|
||||||
|
comment.value = "";
|
||||||
|
}else{
|
||||||
|
await $fetch("/api/comments/courseHeadlineReply", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
id: replyId,
|
||||||
|
text: comment.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
refresh();
|
||||||
|
toast.success("نظر شما با موفقیت ثبت شد");
|
||||||
|
comment.value = "";
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
}
|
|
||||||
|
|
||||||
|
const replyId = ref(null)
|
||||||
|
const reply = async (id) => {
|
||||||
|
replyId.value = id
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
console.log('s',activeHead);
|
|
||||||
function copyUrl() {
|
function copyUrl() {
|
||||||
navigator.clipboard.writeText(window.location.href);
|
navigator.clipboard.writeText(window.location.href);
|
||||||
toast.success("آدرس صفحه کپی شد");
|
toast.success("آدرس صفحه کپی شد");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (query.value.hasOwnProperty("episode")) {
|
if (query.value.hasOwnProperty("episode")) {
|
||||||
const fimd = data.value.find((items) => items.id === query.value.episode);
|
const fimd = data.value.find((items) => items.id === query.value.episode);
|
||||||
activeHead.value = fimd;
|
activeHead.value = fimd;
|
||||||
@@ -455,6 +518,7 @@ const chengeVideo = (item) => {
|
|||||||
});
|
});
|
||||||
refresh();
|
refresh();
|
||||||
};
|
};
|
||||||
|
console.log(activeHead.value.Comment);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -260,10 +260,17 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
|
const { authUser } = useAuth();
|
||||||
|
console.log('user', authUser.value === null);
|
||||||
const props = defineProps(["props"], ["access"]);
|
const props = defineProps(["props"], ["access"]);
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
const router = useRouter()
|
||||||
const paymentHandler = (id) => {
|
const paymentHandler = (id) => {
|
||||||
|
if (authUser.value === null) {
|
||||||
|
return router.push({
|
||||||
|
path: '/login'
|
||||||
|
})
|
||||||
|
}
|
||||||
const data = useFetch("/api/user/registerCourse", {
|
const data = useFetch("/api/user/registerCourse", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
|
|||||||
@@ -59,7 +59,8 @@
|
|||||||
|
|
||||||
<div class="flex gap-[1vw] basis-1/6 md:basis-1/6 w-full text-end justify-end md:pe-[2vw]">
|
<div class="flex gap-[1vw] basis-1/6 md:basis-1/6 w-full text-end justify-end md:pe-[2vw]">
|
||||||
<svg
|
<svg
|
||||||
class="h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
@click="download('دانلود')"
|
||||||
|
class="cursor-pointer h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -95,7 +96,8 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
class="h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
@click="download('مشاهده')"
|
||||||
|
class="cursor-pointer h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
fill="none"
|
fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -143,8 +145,10 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { useToast } from 'vue-toastification'
|
||||||
|
const toast = useToast()
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(['props'])
|
||||||
|
const download = (val) => toast.warning(`برای ${val} باید در دوره شرکت کنید`);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -283,8 +283,8 @@
|
|||||||
|
|
||||||
<nuxt-link to="/account" v-if="authUser">
|
<nuxt-link to="/account" v-if="authUser">
|
||||||
<img
|
<img
|
||||||
v-if="authUser.avatarMedia"
|
v-if="profileImage"
|
||||||
:src="authUser?.avatarMedia"
|
:src="profileImage"
|
||||||
alt="profile"
|
alt="profile"
|
||||||
class="h-[3.698vw] w-[3.698vw] rounded-full p-[0.521vw]"
|
class="h-[3.698vw] w-[3.698vw] rounded-full p-[0.521vw]"
|
||||||
/>
|
/>
|
||||||
@@ -315,6 +315,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="showSearchBox"
|
v-if="showSearchBox"
|
||||||
class="z-[10] w-[28vw] pt-[0.5vw] pb-[2vw] flex flex-col absolute mt-[8vw] rounded-[0.521vw] bg-[#F5F5F5] border shadow-md"
|
class="z-[10] w-[28vw] pt-[0.5vw] pb-[2vw] flex flex-col absolute mt-[8vw] rounded-[0.521vw] bg-[#F5F5F5] border shadow-md"
|
||||||
@@ -356,11 +357,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- <div v-for="item in data.courses" :key="item.id">{{ item.name }}</div> -->
|
<!-- <div v-for="item in data.courses" :key="item.id">{{ item.name }}</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const {data: image} = await useFetch('/api/auth/me')
|
||||||
|
const profileImage = useState('profileImage', () => image.value?.avatarMedia)
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
const showSearchBox = useState("showSearchBox", () => false);
|
const showSearchBox = useState("showSearchBox", () => false);
|
||||||
const search = ref(null);
|
const search = ref(null);
|
||||||
|
|||||||
+7
-2
@@ -284,8 +284,9 @@
|
|||||||
<p
|
<p
|
||||||
class="py-[2vw] md:py-0 text-[17.72px] md:text-[1.502vw] text-[#383E43] mt-[0.417vw]"
|
class="py-[2vw] md:py-0 text-[17.72px] md:text-[1.502vw] text-[#383E43] mt-[0.417vw]"
|
||||||
>
|
>
|
||||||
<span v-if="authUser.name">
|
|
||||||
{{authUser?.name}}
|
<span v-if="profileName">
|
||||||
|
{{profileName}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-else>کاربر</span>
|
<span v-else>کاربر</span>
|
||||||
@@ -341,10 +342,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const {data, refresh} = await useFetch('/api/auth/me')
|
||||||
|
const profileName = useState('profileName', () => data.value.name)
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const {authUser} = useAuth();
|
const {authUser} = useAuth();
|
||||||
@@ -357,6 +361,7 @@ async function logout(){
|
|||||||
toast.warning("از حساب کاربری خود خارج شدید")
|
toast.warning("از حساب کاربری خود خارج شدید")
|
||||||
return navigateTo('/')
|
return navigateTo('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
+44
-22
@@ -38,14 +38,20 @@
|
|||||||
class="mt-[1vw] relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[4vw] md:p-[1.55vw]"
|
class="mt-[1vw] relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[4vw] md:p-[1.55vw]"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="/public/images/client1.png"
|
v-if="item.createdBy?.avatarMedia"
|
||||||
|
:src="item.createdBy.avatarMedia"
|
||||||
|
alt="profile"
|
||||||
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
src="/public/images/alt.png"
|
||||||
alt="profile"
|
alt="profile"
|
||||||
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="ps-[3vw] md:ps-[1vw] w-full">
|
<div class="ps-[3vw] md:ps-[1vw] w-full">
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
علی مصلحی
|
{{ item.createdBy.name ? item.createdBy.name : "کاربر مهمان" }}
|
||||||
</p>
|
</p>
|
||||||
<div class="thin">
|
<div class="thin">
|
||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
@@ -61,17 +67,23 @@
|
|||||||
<div
|
<div
|
||||||
v-for="reply in item.replies"
|
v-for="reply in item.replies"
|
||||||
:key="reply.id"
|
:key="reply.id"
|
||||||
class="relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between ps-[16vw] md:ps-[6vw] p-[2vw] md:p-[1.55vw]"
|
class="relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between ps-[16vw] md:ps-[0vw] p-[2vw] md:p-[1.55vw]"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="/public/images/client3.png"
|
v-if="reply.createdBy.avatarMedia"
|
||||||
|
:src="reply.createdBy.avatarMedia"
|
||||||
|
alt="profile"
|
||||||
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
src="/public/images/alt.png"
|
||||||
alt="profile"
|
alt="profile"
|
||||||
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
class="w-[10.256vw] md:w-[3.958vw] h-[10.256vw] md:h-[3.958vw] rounded-[50%]"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="ps-[3vw] md:ps-[1vw] w-full">
|
<div class="ps-[3vw] md:ps-[1vw] w-full">
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
علی مصلحی
|
{{ reply.createdBy.name ? reply.createdBy.name : 'کاربر مهمان' }}
|
||||||
</p>
|
</p>
|
||||||
<div class="thin">
|
<div class="thin">
|
||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
@@ -109,10 +121,6 @@
|
|||||||
/>
|
/>
|
||||||
</svg> -->
|
</svg> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
@@ -142,7 +150,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="w-full md:w-[23.438vw] text-[#383E43]">
|
<div class="w-full md:w-[23.438vw] text-[#383E43]">
|
||||||
<product-page-course-detailsCourse-status :props="data.course" />
|
<product-page-course-detailsCourse-status :props="data.course" />
|
||||||
<product-page-course-detailsCourse-information :props="[data.course, access]" />
|
<product-page-course-detailsCourse-information
|
||||||
|
:props="[data.course, access]"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -152,14 +162,23 @@
|
|||||||
<div class="space-y-[5vw] md:space-y-[1vw]">
|
<div class="space-y-[5vw] md:space-y-[1vw]">
|
||||||
<div class="flex gap-[1vw]">
|
<div class="flex gap-[1vw]">
|
||||||
<img
|
<img
|
||||||
src="/public/images/client1.png"
|
v-if="authUser?.avatarMedia"
|
||||||
|
:src="authUser.avatarMedia"
|
||||||
|
alt=""
|
||||||
|
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
src="/public/images/alt.png"
|
||||||
alt=""
|
alt=""
|
||||||
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
class="h-[10.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class="space-y-[4vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0"
|
class="space-y-[4vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0"
|
||||||
>
|
>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">علی مصلحی</p>
|
<p class="text-[3.59vw] md:text-[0.938vw]">
|
||||||
|
{{ authUser?.name ? authUser.name : "کاربر مهمان" }}
|
||||||
|
</p>
|
||||||
<p
|
<p
|
||||||
v-if="replayTarget === null"
|
v-if="replayTarget === null"
|
||||||
class="text-[2.836vw] md:text-[0.741vw] text-[#878787]"
|
class="text-[2.836vw] md:text-[0.741vw] text-[#878787]"
|
||||||
@@ -167,7 +186,7 @@
|
|||||||
پرسش جدید
|
پرسش جدید
|
||||||
</p>
|
</p>
|
||||||
<p v-else class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p v-else class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
پاسخ به علی مصلحی
|
پاسخ به کامنت
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,25 +227,28 @@ import { useToast } from "vue-toastification";
|
|||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const replayTarget = ref(null);
|
const replayTarget = ref(null);
|
||||||
const access = ref(false)
|
const access = ref(false);
|
||||||
|
const { authUser } = useAuth();
|
||||||
const { data, refresh } = await useFetch("/api/productId", {
|
const { data, refresh } = await useFetch("/api/productId", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
id: route.params.product,
|
id: route.params.product,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const myCourses = await useFetch('/api/auth/me')
|
const myCourses = await useFetch("/api/auth/me");
|
||||||
myCourses.data.value.course.forEach(element => {
|
myCourses.data.value?.course.forEach((element) => {
|
||||||
if (element.id === route.params.product) {
|
if (element.id === route.params.product) {
|
||||||
access.value = true
|
access.value = true;
|
||||||
}else{
|
} else {
|
||||||
access.value = false
|
access.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
const comment = ref(null);
|
const comment = ref(null);
|
||||||
|
|
||||||
const sendComment = async () => {
|
const sendComment = async () => {
|
||||||
|
if (authUser.value === null) {
|
||||||
|
return toast.warning("برای ثبت نظر ابتدا وارد حساب کاربری خود شوید");
|
||||||
|
}
|
||||||
if (comment.value === "" || comment.value === null) {
|
if (comment.value === "" || comment.value === null) {
|
||||||
return toast.error("متن خود را وارد کنید");
|
return toast.error("متن خود را وارد کنید");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,244 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="flex w-full flex-col pb-[30vw] md:pb-[7vw]">
|
|
||||||
<template>
|
|
||||||
<div class="flex items-center flex-col pb-[25vw] md:pb-[6vw]">
|
|
||||||
<div
|
|
||||||
class="flex flex-col gap-[1vw] flex-col-reverse md:flex-row justify-between w-[87.69%] md:w-full mt-[8.2vw]"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="w-full md:w-[56.354vw] text-[#383E43] text-[1.055vw] leading-[1.582vw]"
|
|
||||||
>
|
|
||||||
|
|
||||||
|
|
||||||
<product-page-attended-coursesVideo />
|
|
||||||
<product-page-attended-coursesDownload-box />
|
|
||||||
<product-page-attended-coursesChats />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w-full md:w-[23.438vw]">
|
|
||||||
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="mt-[82vw] md:mt-[4.6vw] min-h-[87.692vw] md:min-h-[29.635vw] rounded-[3.846vw] md:rounded-[0.781vw] bg-[#F8F8F8] pinkShadow space-y-[2vw] thin"
|
|
||||||
>
|
|
||||||
<div class="flexBox w-full flex-col text-[0.938vw] text-[#878787]">
|
|
||||||
<label
|
|
||||||
v-for="item in data.course.courseHeadlines" :key="item.id"
|
|
||||||
class="h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
|
||||||
>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
<input type="radio" class="accent-primaryGreen" />
|
|
||||||
{{ item.headline }}
|
|
||||||
</div>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
02:24
|
|
||||||
<svg
|
|
||||||
class="h-[4.359vw] w-[4.359vw] md:h-[0.99vw] md:w-[0.99vw]"
|
|
||||||
viewBox="0 0 19 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#clip0_1_896)">
|
|
||||||
<path
|
|
||||||
d="M17.4166 10C17.4166 14.37 13.8699 17.9167 9.49992 17.9167C5.12992 17.9167 1.58325 14.37 1.58325 10C1.58325 5.63001 5.12992 2.08334 9.49992 2.08334C13.8699 2.08334 17.4166 5.63001 17.4166 10Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12.437 12.5175L9.98286 11.0529C9.55536 10.7996 9.20703 10.19 9.20703 9.69124V6.4454"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_1_896">
|
|
||||||
<rect
|
|
||||||
width="19"
|
|
||||||
height="19"
|
|
||||||
fill="white"
|
|
||||||
transform="translate(0 0.5)"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<!-- <label
|
|
||||||
class="bg-[#FDF4FB] h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
|
||||||
>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
checked="checked"
|
|
||||||
class="accent-primaryGreen"
|
|
||||||
/>
|
|
||||||
آشنایی با ساختار صفحات
|
|
||||||
</div>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
08:44
|
|
||||||
<svg
|
|
||||||
class="h-[4.359vw] w-[4.359vw] md:h-[0.99vw] md:w-[0.99vw]"
|
|
||||||
viewBox="0 0 19 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#clip0_1_896)">
|
|
||||||
<path
|
|
||||||
d="M17.4166 10C17.4166 14.37 13.8699 17.9167 9.49992 17.9167C5.12992 17.9167 1.58325 14.37 1.58325 10C1.58325 5.63001 5.12992 2.08334 9.49992 2.08334C13.8699 2.08334 17.4166 5.63001 17.4166 10Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12.437 12.5175L9.98286 11.0529C9.55536 10.7996 9.20703 10.19 9.20703 9.69124V6.4454"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_1_896">
|
|
||||||
<rect
|
|
||||||
width="19"
|
|
||||||
height="19"
|
|
||||||
fill="white"
|
|
||||||
transform="translate(0 0.5)"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label
|
|
||||||
class="h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
|
||||||
>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
<input type="radio" class="accent-primaryGreen" />
|
|
||||||
تگ های Heading
|
|
||||||
</div>
|
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
|
||||||
07:41
|
|
||||||
<svg
|
|
||||||
class="h-[4.359vw] w-[4.359vw] md:h-[0.99vw] md:w-[0.99vw]"
|
|
||||||
viewBox="0 0 19 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<g clip-path="url(#clip0_1_896)">
|
|
||||||
<path
|
|
||||||
d="M17.4166 10C17.4166 14.37 13.8699 17.9167 9.49992 17.9167C5.12992 17.9167 1.58325 14.37 1.58325 10C1.58325 5.63001 5.12992 2.08334 9.49992 2.08334C13.8699 2.08334 17.4166 5.63001 17.4166 10Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M12.437 12.5175L9.98286 11.0529C9.55536 10.7996 9.20703 10.19 9.20703 9.69124V6.4454"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_1_896">
|
|
||||||
<rect
|
|
||||||
width="19"
|
|
||||||
height="19"
|
|
||||||
fill="white"
|
|
||||||
transform="translate(0 0.5)"
|
|
||||||
/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</label> -->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<product-page-attended-coursesProgress-bar />
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { useToast } from "vue-toastification";
|
|
||||||
const toast = useToast();
|
|
||||||
const route = useRoute();
|
|
||||||
const replayTarget = ref(null);
|
|
||||||
const { data, refresh } = await useFetch("/api/productId", {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
id: route.params.product,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const courseHeadline = await useFetch("/api/courseHeadlines", {
|
|
||||||
method: 'POST',
|
|
||||||
query: {
|
|
||||||
id: route.params.product
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log(courseHeadline.data.value);
|
|
||||||
const comment = ref(null);
|
|
||||||
|
|
||||||
const sendComment = async () => {
|
|
||||||
if (comment.value === "" || comment.value === null) {
|
|
||||||
return toast.error("متن خود را وارد کنید");
|
|
||||||
}
|
|
||||||
const comments = await useFetch("/api/comments/sendcomment", {
|
|
||||||
method: "POST",
|
|
||||||
query: {
|
|
||||||
id: data.value.course._id,
|
|
||||||
},
|
|
||||||
body: {
|
|
||||||
text: comment.value,
|
|
||||||
parent: replayTarget.value,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
comment.value = null;
|
|
||||||
toast.success("نظر شما با موفقیت ثبت شد");
|
|
||||||
refresh();
|
|
||||||
};
|
|
||||||
|
|
||||||
const sendReplay = (id) => {
|
|
||||||
replayTarget.value = id;
|
|
||||||
};
|
|
||||||
const deleteComment = () => {
|
|
||||||
replayTarget.value = null;
|
|
||||||
comment.value = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
+20
-3
@@ -11,7 +11,7 @@
|
|||||||
<p
|
<p
|
||||||
class="text-[3.59vw] md:text-[1.055vw] font-[600] text-[#383E43]"
|
class="text-[3.59vw] md:text-[1.055vw] font-[600] text-[#383E43]"
|
||||||
>
|
>
|
||||||
1 روز
|
{{ roundDay }} روز
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="text-[2.836vw] md:text-[0.741vw] font-[400] text-[#383E43]"
|
class="text-[2.836vw] md:text-[0.741vw] font-[400] text-[#383E43]"
|
||||||
@@ -373,8 +373,8 @@
|
|||||||
|
|
||||||
<div class="flex justify-center items-center flex-col mt-[1.823vw]">
|
<div class="flex justify-center items-center flex-col mt-[1.823vw]">
|
||||||
<img
|
<img
|
||||||
v-if="authUser.avatarMedia"
|
v-if="profileImage"
|
||||||
:src="authUser?.avatarMedia"
|
:src="profileImage"
|
||||||
class="h-[27.949vw] md:h-[7.24vw] w-[27.949vw] md:w-[7.24vw] rounded-full"
|
class="h-[27.949vw] md:h-[7.24vw] w-[27.949vw] md:w-[7.24vw] rounded-full"
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
@@ -530,6 +530,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const profileImage = useState('profileImage')
|
||||||
const tickets = await useFetch("/api/ticket");
|
const tickets = await useFetch("/api/ticket");
|
||||||
const lastTickets = tickets.data.value.slice(-2);
|
const lastTickets = tickets.data.value.slice(-2);
|
||||||
const myCourses = await useFetch("/api/auth/me");
|
const myCourses = await useFetch("/api/auth/me");
|
||||||
@@ -537,6 +538,22 @@ const lastCourses = myCourses.data.value.course.slice(-2);
|
|||||||
const balance = await useFetch("/api/user/balance");
|
const balance = await useFetch("/api/user/balance");
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
|
|
||||||
|
const today = new Date(); // تاریخ امروز
|
||||||
|
const pastDate = new Date(authUser.value.createdAt); // تاریخ گذشته
|
||||||
|
|
||||||
|
// تفاوت زمانی را محاسبه میکنیم
|
||||||
|
const timeDifference = today.getTime() - pastDate.getTime();
|
||||||
|
|
||||||
|
// تبدیل میلیثانیه به روز
|
||||||
|
const dayDifference = timeDifference / (1000 * 3600 * 24);
|
||||||
|
const roundDay = Math.ceil(dayDifference)
|
||||||
|
|
||||||
|
console.log(`تفاوت بین تاریخ امروز و تاریخ گذشته: ${roundDay} روز`);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log(today);
|
||||||
|
console.log(today - authUser.value.createdAt);
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth",
|
middleware: "auth",
|
||||||
});
|
});
|
||||||
|
|||||||
+40
-24
@@ -2,8 +2,8 @@
|
|||||||
<div class="flex justify-between flex-col text-[#383E43]">
|
<div class="flex justify-between flex-col text-[#383E43]">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<img
|
<img
|
||||||
v-if="authUser.avatarMedia"
|
v-if="profileImage"
|
||||||
:src="authUser?.avatarMedia"
|
:src="profileImage"
|
||||||
class="w-[40.256vw] md:w-[8.177vw] h-[40.256vw] md:h-[8.177vw] rounded-[50%]"
|
class="w-[40.256vw] md:w-[8.177vw] h-[40.256vw] md:h-[8.177vw] rounded-[50%]"
|
||||||
alt="profile"
|
alt="profile"
|
||||||
/>
|
/>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
<input type="file" id="file-upload" @change="changePhoto"/>
|
<input type="file" id="file-upload" @change="changePhoto" />
|
||||||
</div>
|
</div>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="form"
|
type="form"
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="name"
|
||||||
:value="authUser?.phone"
|
:value="data?.phone"
|
||||||
readonly
|
readonly
|
||||||
class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
||||||
/>
|
/>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="name"
|
name="name"
|
||||||
:value="authUser?.name"
|
:value="data?.name"
|
||||||
type="text"
|
type="text"
|
||||||
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
||||||
/>
|
/>
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="userName"
|
name="userName"
|
||||||
:value="authUser?.userName"
|
:value="data?.userName"
|
||||||
type="text"
|
type="text"
|
||||||
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
||||||
/>
|
/>
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="email"
|
name="email"
|
||||||
:value="authUser?.email"
|
:value="data?.email"
|
||||||
type="text"
|
type="text"
|
||||||
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
input-class="bg-[#F5F5F5] h-[13.59vw] md:h-[2.969vw] w-full md:w-[19.01vw] rounded-[2.564vw] md:rounded-[0.521vw] px-[1vw]"
|
||||||
/>
|
/>
|
||||||
@@ -147,51 +147,67 @@
|
|||||||
</div>
|
</div>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
const profileName = useState('profileName')
|
||||||
|
const profileImage = useState('profileImage')
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const name = ref("avater");
|
const {data, refresh} = await useFetch('/api/auth/me')
|
||||||
|
|
||||||
const edit = async (formData) => {
|
const edit = async (formData) => {
|
||||||
|
|
||||||
|
if (formData.name !== authUser.value.name) {
|
||||||
|
profileName.value = formData.name
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await $fetch("/api/user/update", {
|
await $fetch("/api/user/update", {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: formData,
|
body: formData,
|
||||||
});
|
});
|
||||||
location.reload();
|
toast.success('اطلاعات با موفقیت ویرایش شد')
|
||||||
|
refresh()
|
||||||
|
// location.reload();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error);
|
toast.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//const token = getCookie(event, 'token');
|
||||||
async function changePhoto(val) {
|
async function changePhoto(val) {
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', val.target.files[0]);
|
formData.append("directoryName", "test");
|
||||||
formData.append('directoryName', name.value);
|
formData.append("file", val.target.files[0]);
|
||||||
|
|
||||||
try {
|
const data = await useFetch("/api/uploader", {
|
||||||
const dataa = await $fetch("/api/uploader", {
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData
|
body: formData,
|
||||||
});
|
});
|
||||||
console.log('dataa',dataa);
|
|
||||||
} catch (error) {
|
|
||||||
console.log('error client', error.data.data.message);
|
|
||||||
}
|
|
||||||
// console.log('ss', formData);
|
|
||||||
|
|
||||||
// const data = await useFetch("api/uploader", {
|
if (data.data.value.url) {
|
||||||
// method: 'POST',
|
console.log('done');
|
||||||
// body: formData
|
await $fetch("/api/user/update", {
|
||||||
// });
|
method: "PUT",
|
||||||
|
body: {
|
||||||
|
avatarMedia: data.data.value.url
|
||||||
|
},
|
||||||
|
});
|
||||||
|
profileImage.value = data.data.value.url
|
||||||
|
toast.success('تصویر پروفایل تغییر کرد')
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ item.reason }}
|
{{ item.reason === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ numberFormat(item.amount) }}
|
{{ numberFormat(item.amount) }}
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
class="flex justify-between items-center"
|
class="flex justify-between items-center"
|
||||||
>
|
>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ item.reason }}
|
{{ item.reason === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ numberFormat(item.amount) }}
|
{{ numberFormat(item.amount) }}
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
class="flex justify-between items-center"
|
class="flex justify-between items-center"
|
||||||
>
|
>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ item.reason }}
|
{{ item.reason === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ numberFormat(item.amount) }}
|
{{ numberFormat(item.amount) }}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
const body = await readBody(event);
|
||||||
|
console.log(body);
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/courseHeadlineComment/reply`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -13,10 +13,10 @@ export default defineEventHandler(async (event) => {
|
|||||||
},
|
},
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
|
console.log(data);
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/common/settings`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'content-type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
+17
-14
@@ -4,32 +4,35 @@ import fs from 'fs';
|
|||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const { public: { apiBase } } = useRuntimeConfig();
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
const token = getCookie(event, 'token');
|
const token = getCookie(event, 'token');
|
||||||
// const body = await readBody(event);
|
|
||||||
// console.log('body', body);
|
|
||||||
const { fields, files } = await readFiles(event, {
|
|
||||||
includeFields: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
// const { fields, files } = await readFiles(event, {
|
||||||
|
// includeFields: true,
|
||||||
|
// })
|
||||||
|
const formData = await readFormData(event);
|
||||||
|
console.log(formData);
|
||||||
|
// const form = new FormData()
|
||||||
|
// form.append('directoryName', fields.directoryName[0])
|
||||||
|
// form.append('file', fs.createReadStream(files.file[0].filepath))
|
||||||
|
// console.log('files', files);
|
||||||
|
// console.log('file[0]', files.file[0]);
|
||||||
|
// console.log('form', form);
|
||||||
|
// for (var pair of form.entries()) {
|
||||||
|
// console.log('pairs :', pair[0] + ', ' + pair[1]);
|
||||||
|
// }
|
||||||
|
|
||||||
var formDat = new FormData();
|
|
||||||
formDat.append('directoryName', fields.directoryName[0]);
|
|
||||||
formDat.append('file', fs.createReadStream(files.file[0].filepath));
|
|
||||||
// console.log('path',files.file[0].filepath);
|
|
||||||
// console.log('text',fields.directoryName[0]);
|
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/uploader`, {
|
const data = await $fetch(`${apiBase}/uploader`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formDat,
|
body: formData,
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
//'Content-Type': 'multipart/form-data',
|
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log('uplodar',data);
|
console.log('uplodar', data);
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error.data);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
const data = await $fetch(`${apiBase}/user/update`, {
|
const data = await $fetch(`${apiBase}/user/update`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
body: {
|
body: {
|
||||||
avatarMediaId: "",
|
avatarMedia: body.avatarMedia,
|
||||||
name: body.name,
|
name: body.name,
|
||||||
lastName: "",
|
lastName: "",
|
||||||
userName: "",
|
userName: "",
|
||||||
|
|||||||
Reference in New Issue
Block a user