publication v-1
This commit is contained in:
@@ -4,10 +4,10 @@
|
|||||||
<p
|
<p
|
||||||
class="text-black post w-[30.769vw] md:w-[6.979vw] h-[9.487vw] md:h-[2.24vw] flexBox text-[3.59vw] md:text-[0.938vw] absolute left-0 bottom-0 bg-white rounded-tr-[3.59vw] md:rounded-tr-[0.781vw]">
|
class="text-black post w-[30.769vw] md:w-[6.979vw] h-[9.487vw] md:h-[2.24vw] flexBox text-[3.59vw] md:text-[0.938vw] absolute left-0 bottom-0 bg-white rounded-tr-[3.59vw] md:rounded-tr-[0.781vw]">
|
||||||
|
|
||||||
{{ props.item?.price > 0 ? numberFormat(props.item?.price) + 'تومان' : 'رایگان' }}
|
{{ props.item?.item.price > 0 ? numberFormat(props.item?.item.price) + 'تومان' : 'رایگان' }}
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<NuxtImg style="object-fit: cover;" :src="props.item?.image"
|
<NuxtImg style="object-fit: cover;" :src="props.item?.item.image"
|
||||||
:placeholder="[30, 20]"
|
:placeholder="[30, 20]"
|
||||||
alt="laravel"
|
alt="laravel"
|
||||||
class="h-[56.154vw] md:h-[11.406vw] w-full rounded-[3.846vw] md:rounded-[0.781vw]"
|
class="h-[56.154vw] md:h-[11.406vw] w-full rounded-[3.846vw] md:rounded-[0.781vw]"
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<p @click="change"
|
<p @click="change"
|
||||||
class="cursor-pointer mb-[15vw] md:mb-[2.5vw] text-[14px] md:text-[0.833vw] text-[#383E43] ] mt-[4vw] md:mt-[1.042vw] ms-[3vw] md:ms-[0.625vw]"
|
class="cursor-pointer mb-[15vw] md:mb-[2.5vw] text-[14px] md:text-[0.833vw] text-[#383E43] ] mt-[4vw] md:mt-[1.042vw] ms-[3vw] md:ms-[0.625vw]"
|
||||||
>
|
>
|
||||||
{{ props.item?.name }}
|
{{ props.item?.item.name }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -28,13 +28,14 @@
|
|||||||
>
|
>
|
||||||
<div class="flex justify-between w-full mb-[0.417vw]">
|
<div class="flex justify-between w-full mb-[0.417vw]">
|
||||||
<p class="text-[2.836vw] md:text-[0.658vw] text-[#383E43]">میزان مشاهده</p>
|
<p class="text-[2.836vw] md:text-[0.658vw] text-[#383E43]">میزان مشاهده</p>
|
||||||
<p class="text-[3.19vw] md:text-[0.741vw] text-[#383E43]">0 %</p>
|
<p class="text-[3.19vw] md:text-[0.741vw] text-[#383E43]">{{ Math.floor(props.item.completionPercentage) }} %</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="progressbar"
|
id="progressbar"
|
||||||
class="mt-[3vw] md:mt-[0vw] h-[2.051vw] md:h-[0.26vw] rounded-[2vw] md:rounded-[0.521vw]"
|
class="mt-[3vw] md:mt-[0vw] h-[2.051vw] md:h-[0.26vw] rounded-[2vw] md:rounded-[0.521vw]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
:style="{ width: activeClass + '%' }"
|
||||||
class="rounded-[2vw] md:rounded-[0.521vw] h-[2.051vw] md:h-[0.26vw]"
|
class="rounded-[2vw] md:rounded-[0.521vw] h-[2.051vw] md:h-[0.26vw]"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -45,10 +46,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
|
||||||
const props = defineProps(['item']);
|
const props = defineProps(['item']);
|
||||||
|
|
||||||
|
const activeClass = ref(props.item.completionPercentage);
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const change = () =>{
|
const change = () =>{
|
||||||
router.replace(`/${props.item.id}`)
|
router.replace(`/${props.item.item.id}`)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -80,7 +83,6 @@ const change = () =>{
|
|||||||
}
|
}
|
||||||
#progressbar > div {
|
#progressbar > div {
|
||||||
background-color: #0d3f40;
|
background-color: #0d3f40;
|
||||||
width: 77%;
|
|
||||||
float: left;
|
float: left;
|
||||||
|
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
>
|
>
|
||||||
درباره ما
|
درباره ما
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<div
|
||||||
class="about text-[#383E43] max-w-[766px] text-[3.59vw] md:text-[1.335vw] mt-[4vw] md:mt-[1.354vw] mb-[6vw] md:mb-0 leading-[7.179vw] md:leading-[2.865vw]"
|
v-html="info.data.value.about"
|
||||||
|
class="about text-[#383E43] max-w-[766px] text-[3.59vw] md:text-[16px] mt-[4vw] md:mt-[1.354vw] mb-[6vw] md:mb-0 leading-[7.179vw] font-light md:leading-[1.865vw]"
|
||||||
>
|
>
|
||||||
|
</div>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative basis-1/1 md:basis-1/2">
|
<div class="relative basis-1/1 md:basis-1/2">
|
||||||
@@ -29,9 +29,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
const info = await useFetch('/api/settings')
|
const info = await useFetch('/api/settings')
|
||||||
if (process.client) {
|
|
||||||
document.querySelector('.about').innerHTML = info.data.value.about
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div
|
<div
|
||||||
class="courses"
|
class="courses"
|
||||||
>
|
>
|
||||||
<div class="category">
|
<div class="hidden md:block category">
|
||||||
<h3
|
<h3
|
||||||
class="font-semibold text-[#383E43] text-[5.11vw] md:text-[1.69vw] mt-[4.103vw] md:mt-[3.49vw] ms-0 md:ms-[1.563vw]"
|
class="font-semibold text-[#383E43] text-[5.11vw] md:text-[1.69vw] mt-[4.103vw] md:mt-[3.49vw] ms-0 md:ms-[1.563vw]"
|
||||||
>
|
>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- <home-page-courses-sectionCategories /> -->
|
<!-- <home-page-courses-sectionCategories /> -->
|
||||||
<div
|
<div
|
||||||
class="suggestions px-[1vw] md:px-[1.042vw] mt-[12vw] md:mt-[3.2vw] md:bg-white rounded-[0.781vw] flex flex-col gap-[0.417vw] pb-[1.667vw]"
|
class="suggestions px-[1vw] md:px-[1.042vw] mt-[8vw] md:mt-[3.2vw] md:bg-white rounded-[0.781vw] flex flex-col gap-[0.417vw] pb-[1.667vw]"
|
||||||
>
|
>
|
||||||
<h5
|
<h5
|
||||||
class="border-b pb-[1.5vw] text-[4.544vw] mt-[1.5vw] md:mt-[1.6vw] md:text-[1.481vw] text-[#383E43] font-bold"
|
class="border-b pb-[1.5vw] text-[4.544vw] mt-[1.5vw] md:mt-[1.6vw] md:text-[1.481vw] text-[#383E43] font-bold"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<p v-if="timer > 0" class="text-[3vw] md:text-[0.7vw] px-[2vw] md:px-[1vw] text-primaryGreen">
|
<p v-if="timer > 0" class="text-[3vw] md:text-[0.7vw] px-[2vw] md:px-[1vw] text-primaryGreen">
|
||||||
0{{ timer }} : 00
|
00:{{ timer < 10 ? '0' + timer : timer }}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
v-else
|
v-else
|
||||||
@@ -129,7 +129,7 @@ const code = ref(null);
|
|||||||
const errors = ref([]);
|
const errors = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const phoneNumber = useState("phoneNumber");
|
const phoneNumber = useState("phoneNumber");
|
||||||
const timer = ref(5);
|
const timer = ref(59);
|
||||||
|
|
||||||
async function checkOtp() {
|
async function checkOtp() {
|
||||||
if (code.value == null) {
|
if (code.value == null) {
|
||||||
@@ -151,6 +151,7 @@ const timer = ref(5);
|
|||||||
if (data.status === "Active") {
|
if (data.status === "Active") {
|
||||||
toast.success("ورود با موفقیت انجام شد")
|
toast.success("ورود با موفقیت انجام شد")
|
||||||
authUser.value = data;
|
authUser.value = data;
|
||||||
|
location.reload()
|
||||||
navigateTo("/");
|
navigateTo("/");
|
||||||
}
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -173,7 +174,7 @@ async function resendSMS() {
|
|||||||
});
|
});
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
toast.success("کد مجدد برای شما ارسال شد")
|
toast.success("کد مجدد برای شما ارسال شد")
|
||||||
timer.value = 5;
|
timer.value = 59;
|
||||||
options.value = false;
|
options.value = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -194,7 +195,7 @@ async function resendCall() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
toast.success("درحال تماس با شما هستیم...")
|
toast.success("درحال تماس با شما هستیم...")
|
||||||
timer.value = 5;
|
timer.value = 59;
|
||||||
options.value = false;
|
options.value = false;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -45,19 +45,20 @@
|
|||||||
<h1>{{ activeHead?.description }}</h1>
|
<h1>{{ activeHead?.description }}</h1>
|
||||||
<p
|
<p
|
||||||
@click="nextHandler(item)"
|
@click="nextHandler(item)"
|
||||||
class="hidden animate-bounce next text-[0.75vw] cursor-pointer flex items-center gap-[0.3vw] pe-[1vw]"
|
class="hidden animate-bounce next text-[2.5vw] absolute md:top-0 left-0 top-[7vw] md:text-[0.75vw] cursor-pointer flex items-center gap-[0.3vw] md:pe-[1vw]"
|
||||||
>
|
>
|
||||||
مشاهده قسمت بعد
|
مشاهده قسمت بعد
|
||||||
<img
|
<img
|
||||||
src="/public/images/next-svgrepo-com.svg"
|
src="/public/images/next-svgrepo-com.svg"
|
||||||
alt=""
|
alt=""
|
||||||
class="h-[0.8vw] rotate-180"
|
class="h-[3vw] md:h-[0.8vw] rotate-180"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute gap-[2vw] flex md:hidden left-0">
|
<div class="absolute gap-[2vw] flex md:hidden left-0">
|
||||||
<svg
|
<svg
|
||||||
|
@click="copyUrl"
|
||||||
class="h-[5.641vw] w-[5.641vw]"
|
class="h-[5.641vw] w-[5.641vw]"
|
||||||
viewBox="0 0 24 22"
|
viewBox="0 0 24 22"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -113,45 +114,47 @@
|
|||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
<a :href="url" class="h-[5.641vw] w-[5.641vw]">
|
||||||
|
<svg
|
||||||
|
|
||||||
<svg
|
class="h-[5.641vw] w-[5.641vw]"
|
||||||
class="h-[5.641vw] w-[5.641vw]"
|
viewBox="0 0 22 22"
|
||||||
viewBox="0 0 22 22"
|
fill="none"
|
||||||
fill="none"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
>
|
||||||
>
|
<g clip-path="url(#clip0_1_6599)">
|
||||||
<g clip-path="url(#clip0_1_6599)">
|
<path
|
||||||
<path
|
d="M8.54333 10.7068L10.89 13.0535L13.2367 10.7068"
|
||||||
d="M8.54333 10.7068L10.89 13.0535L13.2367 10.7068"
|
stroke="#383E43"
|
||||||
stroke="#383E43"
|
stroke-width="1.5"
|
||||||
stroke-width="1.5"
|
stroke-miterlimit="10"
|
||||||
stroke-miterlimit="10"
|
stroke-linecap="round"
|
||||||
stroke-linecap="round"
|
stroke-linejoin="round"
|
||||||
stroke-linejoin="round"
|
/>
|
||||||
/>
|
<path
|
||||||
<path
|
d="M10.89 3.66675V12.9892"
|
||||||
d="M10.89 3.66675V12.9892"
|
stroke="#383E43"
|
||||||
stroke="#383E43"
|
stroke-width="1.5"
|
||||||
stroke-width="1.5"
|
stroke-miterlimit="10"
|
||||||
stroke-miterlimit="10"
|
stroke-linecap="round"
|
||||||
stroke-linecap="round"
|
stroke-linejoin="round"
|
||||||
stroke-linejoin="round"
|
/>
|
||||||
/>
|
<path
|
||||||
<path
|
d="M18.3334 11.165C18.3334 15.2167 15.5834 18.4984 11 18.4984C6.41669 18.4984 3.66669 15.2167 3.66669 11.165"
|
||||||
d="M18.3334 11.165C18.3334 15.2167 15.5834 18.4984 11 18.4984C6.41669 18.4984 3.66669 15.2167 3.66669 11.165"
|
stroke="#383E43"
|
||||||
stroke="#383E43"
|
stroke-width="1.5"
|
||||||
stroke-width="1.5"
|
stroke-miterlimit="10"
|
||||||
stroke-miterlimit="10"
|
stroke-linecap="round"
|
||||||
stroke-linecap="round"
|
stroke-linejoin="round"
|
||||||
stroke-linejoin="round"
|
/>
|
||||||
/>
|
</g>
|
||||||
</g>
|
<defs>
|
||||||
<defs>
|
<clipPath id="clip0_1_6599">
|
||||||
<clipPath id="clip0_1_6599">
|
<rect width="22" height="22" fill="white" />
|
||||||
<rect width="22" height="22" fill="white" />
|
</clipPath>
|
||||||
</clipPath>
|
</defs>
|
||||||
</defs>
|
</svg>
|
||||||
</svg>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -273,9 +276,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="item in activeHead.Comment"
|
v-for="item in activeHead.Comment"
|
||||||
v-show="item.status === 'Active'"
|
|
||||||
:key="item.id"
|
: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]"
|
class="mt-[1vw] relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[4vw] md:p-[1.55vw]"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-if="item.user?.avatarMedia"
|
v-if="item.user?.avatarMedia"
|
||||||
@@ -295,9 +297,9 @@
|
|||||||
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
<p class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ item.user.name ? item.user.name : "کاربر مهمان" }}
|
{{ item.user.name ? item.user.name : "کاربر مهمان" }}
|
||||||
</p>
|
</p>
|
||||||
<div class="thin">
|
<div class="thin mt-[4vw] md:mt-0">
|
||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
{{ jDate(item.createdAt) }}
|
|
||||||
</p>
|
</p>
|
||||||
<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]"
|
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]"
|
||||||
@@ -307,7 +309,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svg
|
<!-- <svg
|
||||||
@click="reply(item.id)"
|
@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]"
|
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"
|
viewBox="0 0 24 24"
|
||||||
@@ -329,7 +331,7 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg> -->
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-[#F8F8F8] p-[4vw] md:p-[1vw] rounded-[3.846vw] md:rounded-[0.781vw] mt-[6vw] md:mt-[2vw]"
|
class="bg-[#F8F8F8] p-[4vw] md:p-[1vw] rounded-[3.846vw] md:rounded-[0.781vw] mt-[6vw] md:mt-[2vw]"
|
||||||
@@ -337,8 +339,8 @@
|
|||||||
<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
|
||||||
v-if="authUser.avatarMedia"
|
v-if="authUser.user.avatarMedia"
|
||||||
:src="authUser.avatarMedia"
|
:src="authUser.user.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%]"
|
||||||
/>
|
/>
|
||||||
@@ -352,7 +354,7 @@
|
|||||||
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 class="text-[3.59vw] md:text-[0.938vw]">
|
||||||
{{ authUser?.name ? authUser.name : "کاربر مهمان" }}
|
{{ authUser?.user.name ? authUser.user.name : "کاربر مهمان" }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
پرسش جدید
|
پرسش جدید
|
||||||
@@ -474,6 +476,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
watchEffect(() =>{
|
||||||
|
if (process.client) {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -485,21 +495,45 @@ const toast = useToast();
|
|||||||
const comment = ref(null);
|
const comment = ref(null);
|
||||||
const index = ref(0);
|
const index = ref(0);
|
||||||
query.value = route.query;
|
query.value = route.query;
|
||||||
const { authUser } = useAuth();
|
const episodeId = ref(null)
|
||||||
|
|
||||||
const { data: progress, refresh: reload } = await useFetch("/api/progress", {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
id: route.params.product,
|
|
||||||
userId: authUser.value.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const activeClass = ref(progress.value.completionPercentage);
|
|
||||||
const { data, refresh } = await useFetch("/api/courseHeadlines", {
|
const { data, refresh } = await useFetch("/api/courseHeadlines", {
|
||||||
query: {
|
query: {
|
||||||
id: route.params.product,
|
id: route.params.product,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const { authUser } = useAuth();
|
||||||
|
async function addToProgress() {
|
||||||
|
await $fetch("/api/progressCounter", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
id: episodeId.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
watchEffect(() =>{
|
||||||
|
if (route.query.episode === undefined) {
|
||||||
|
episodeId.value = data.value[0].id
|
||||||
|
}else{
|
||||||
|
episodeId.value = route.query.episode
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('route', episodeId.value);
|
||||||
|
console.log(data.value[0].id);
|
||||||
|
const { data: progress, refresh: reload } = await useFetch("/api/progress", {
|
||||||
|
query: {
|
||||||
|
id: route.params.product,
|
||||||
|
userId: authUser.value.user.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const activeClass = ref(progress.value.completionPercentage);
|
||||||
|
watchEffect(()=>{
|
||||||
|
activeClass.value = progress.value.completionPercentage;
|
||||||
|
})
|
||||||
|
|
||||||
function convertStoMs(seconds) {
|
function convertStoMs(seconds) {
|
||||||
let minutes = Math.floor(seconds / 60);
|
let minutes = Math.floor(seconds / 60);
|
||||||
let extraSeconds = seconds % 60;
|
let extraSeconds = seconds % 60;
|
||||||
@@ -513,19 +547,13 @@ function convertStoMs(seconds) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addToProgress() {
|
|
||||||
await $fetch("/api/progressCounter", {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
id: route.query.episode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
import progressAlert from "@/components/progressAlert.vue";
|
import progressAlert from "@/components/progressAlert.vue";
|
||||||
const handleVideoEnded = async () => {
|
const handleVideoEnded = async () => {
|
||||||
|
activeClass.value = progress.value.completionPercentage;
|
||||||
addToProgress();
|
addToProgress();
|
||||||
|
|
||||||
reload();
|
reload();
|
||||||
|
refresh();
|
||||||
|
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
document.querySelector(".next").classList.remove("hidden");
|
document.querySelector(".next").classList.remove("hidden");
|
||||||
}
|
}
|
||||||
@@ -596,6 +624,10 @@ if (query.value.hasOwnProperty("episode")) {
|
|||||||
async function chengeVideo(item) {
|
async function chengeVideo(item) {
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
document.querySelector(".next").classList.add("hidden");
|
document.querySelector(".next").classList.add("hidden");
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
query.value = { ...route.query, episode: item.id };
|
query.value = { ...route.query, episode: item.id };
|
||||||
activeHead.value = item;
|
activeHead.value = item;
|
||||||
@@ -615,6 +647,7 @@ async function chengeVideo(item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function nextHandler() {
|
async function nextHandler() {
|
||||||
|
addToProgress();
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
document.querySelector(".next").classList.add("hidden");
|
document.querySelector(".next").classList.add("hidden");
|
||||||
}
|
}
|
||||||
@@ -627,7 +660,7 @@ async function nextHandler() {
|
|||||||
// id: route.query.episode,
|
// id: route.query.episode,
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
addToProgress();
|
|
||||||
activeHead.value = data.value[index.value];
|
activeHead.value = data.value[index.value];
|
||||||
const getUrl = await useFetch("/api/checkMedia", {
|
const getUrl = await useFetch("/api/checkMedia", {
|
||||||
query: {
|
query: {
|
||||||
@@ -636,7 +669,7 @@ async function nextHandler() {
|
|||||||
});
|
});
|
||||||
url.value = getUrl.data.value.url;
|
url.value = getUrl.data.value.url;
|
||||||
video.value.load();
|
video.value.load();
|
||||||
activeClass.value = progress.value.completionPercentage;
|
// activeClass.value = progress.value.completionPercentage;
|
||||||
refresh();
|
refresh();
|
||||||
reload();
|
reload();
|
||||||
router.push({
|
router.push({
|
||||||
|
|||||||
@@ -113,7 +113,7 @@
|
|||||||
حجم فایل ها
|
حجم فایل ها
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[#383E43] font-semibold">
|
<p class="text-[#383E43] font-semibold">
|
||||||
{{ props.props[0].totalFileSize }}
|
{{ props.props[0].totalFileSize }} گیگابایت
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="py-[3vw] md:py-[0.9vw] w-full border-b flex justify-between">
|
<div class="py-[3vw] md:py-[0.9vw] w-full border-b flex justify-between">
|
||||||
@@ -197,7 +197,9 @@
|
|||||||
|
|
||||||
زبان
|
زبان
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[#383E43] font-semibold">{{ props.props[0].language }}</p>
|
<p class="text-[#383E43] font-semibold">
|
||||||
|
{{ props.props[0].language }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="py-[3vw] md:py-[0.9vw] w-full border-b flex justify-between">
|
<div class="py-[3vw] md:py-[0.9vw] w-full border-b flex justify-between">
|
||||||
<p class="flex items-center gap-[0.8vw] ps-[2vw]">سطح رضایت</p>
|
<p class="flex items-center gap-[0.8vw] ps-[2vw]">سطح رضایت</p>
|
||||||
@@ -251,7 +253,7 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
{{ props.props[1] ? 'مشاهده دوره' : 'شرکت در دوره' }}
|
{{ props.props[1] ? "مشاهده دوره" : "شرکت در دوره" }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -263,32 +265,29 @@ import { useToast } from "vue-toastification";
|
|||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
const props = defineProps(["props"], ["access"]);
|
const props = defineProps(["props"], ["access"]);
|
||||||
|
|
||||||
|
const toast = useToast();
|
||||||
const toast = useToast()
|
const router = useRouter();
|
||||||
const router = useRouter()
|
|
||||||
const paymentHandler = (id) => {
|
const paymentHandler = (id) => {
|
||||||
if (authUser.value === null) {
|
if (authUser.value === null) {
|
||||||
return router.push({
|
return router.push({
|
||||||
path: '/login'
|
path: "/login",
|
||||||
})
|
|
||||||
}
|
|
||||||
const data = useFetch("/api/user/registerCourse", {
|
|
||||||
method: "POST",
|
|
||||||
body: {
|
|
||||||
courseId: id,
|
|
||||||
code: "",
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
const data = useFetch("/api/user/registerCourse", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
courseId: id,
|
||||||
|
code: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (data.data.value?.status === 406 || data.data.value?.status === 500) {
|
if (data.data.value?.status === 406 || data.data.value?.status === 500) {
|
||||||
toast.error(data.data.value.message
|
toast.error(data.data.value.message);
|
||||||
|
} else {
|
||||||
)
|
toast.success("ثبت نام انجام شد");
|
||||||
} else {
|
}
|
||||||
toast.success('ثبت نام انجام شد')
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
}
|
}, 1000);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
>توضیحات</span
|
>توضیحات</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="descriptions mt-[4vw] md:mt-[2.1vw] thin">
|
<div v-html="props.props.description" class="descriptions mt-[4vw] md:mt-[2.1vw] thin">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@@ -25,7 +25,4 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(['props'])
|
||||||
|
|
||||||
if (process.client) {
|
|
||||||
document.querySelector('.descriptions').innerHTML = props.props.description;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
{{ props.props?.categories[0].name }}
|
{{ props.props?.categories[0].name }}
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
|
v-html="describe"
|
||||||
class="descriptios hidden md:block w-[39.896vw] text-[1.055vw] leading-[1.582vw] mt-[1.2vw]"
|
class="descriptios hidden md:block w-[39.896vw] text-[1.055vw] leading-[1.582vw] mt-[1.2vw]"
|
||||||
></div>
|
></div>
|
||||||
<p
|
<p
|
||||||
@@ -199,18 +200,16 @@
|
|||||||
const props = defineProps(["props"]);
|
const props = defineProps(["props"]);
|
||||||
import {jDate} from "@/utils/jDate"
|
import {jDate} from "@/utils/jDate"
|
||||||
|
|
||||||
if (process.client) {
|
|
||||||
const des = props?.props.description;
|
function hideEndOfString(inputString) {
|
||||||
function hideEndOfString(inputString) {
|
const words = inputString.split(" ");
|
||||||
const words = inputString.split(" ");
|
if (words.length > 50) {
|
||||||
if (words.length > 50) {
|
const truncatedWords = words.slice(0, 30);
|
||||||
const truncatedWords = words.slice(0, 50);
|
return truncatedWords.join(" ") + "...";
|
||||||
return truncatedWords.join(" ") + "...";
|
} else {
|
||||||
} else {
|
return inputString;
|
||||||
return inputString;
|
}
|
||||||
}
|
}
|
||||||
}
|
const describe = hideEndOfString(props.props.description);
|
||||||
const data = hideEndOfString(des);
|
|
||||||
document.querySelector(".descriptios").innerHTML = data;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
@@ -30,10 +30,8 @@
|
|||||||
</span>
|
</span>
|
||||||
<h2 class="border-r ps-[2.2vw]">{{ headline.headline }}</h2>
|
<h2 class="border-r ps-[2.2vw]">{{ headline.headline }}</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="hidden md:flex items-center text-[0.833vw] w-full md:basis-2/6">
|
<div class="hidden md:flex items-center text-[0.833vw] w-full md:basis-2/6">
|
||||||
<span>08:55</span>
|
<span>{{ convertStoMs(headline.time) }}</span>
|
||||||
<svg
|
<svg
|
||||||
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
@@ -124,6 +122,18 @@ import { useToast } from 'vue-toastification'
|
|||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(['props'])
|
||||||
const download = (val) => toast.warning(`برای ${val} باید در دوره شرکت کنید`);
|
const download = (val) => toast.warning(`برای ${val} باید در دوره شرکت کنید`);
|
||||||
|
function convertStoMs(seconds) {
|
||||||
|
let minutes = Math.floor(seconds / 60);
|
||||||
|
let extraSeconds = seconds % 60;
|
||||||
|
minutes = minutes < 10 ? "0" + minutes : minutes;
|
||||||
|
return (
|
||||||
|
minutes +
|
||||||
|
":" +
|
||||||
|
(extraSeconds < 10
|
||||||
|
? "0" + Math.floor(extraSeconds)
|
||||||
|
: Math.floor(extraSeconds))
|
||||||
|
);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-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="authUser.user.avatarMedia"
|
||||||
:src="authUser.avatarMedia"
|
:src="authUser.user.avatarMedia"
|
||||||
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]"
|
||||||
/>
|
/>
|
||||||
|
|||||||
+2
-2
@@ -285,8 +285,8 @@
|
|||||||
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">
|
<span v-if="authUser.user.name">
|
||||||
{{authUser.name}}
|
{{authUser.user.name}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span v-else>کاربر</span>
|
<span v-else>کاربر</span>
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nuxt dev",
|
"dev": "nuxt dev",
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
"start": "PORT=5805 HOST=127.0.0.1 node .output/server/index.mjs",
|
"start": "node .output/server/index.mjs",
|
||||||
"generate": "nuxt generate",
|
"generate": "nuxt generate",
|
||||||
"preview": "nuxt preview",
|
"preview": "nuxt preview",
|
||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
|
|||||||
+26
-10
@@ -55,7 +55,7 @@
|
|||||||
</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]">
|
||||||
1402/09/14
|
{{ jDate(item.createdBy.createdAt) }}
|
||||||
</p>
|
</p>
|
||||||
<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]"
|
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]"
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<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-[0vw] p-[2vw] md:p-[1.55vw]"
|
class="relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[2vw] md:p-[1.55vw]"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
v-if="reply.createdBy.avatarMedia"
|
v-if="reply.createdBy.avatarMedia"
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
</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]">
|
||||||
1402/09/14
|
{{ jDate(reply.createdBy.createdAt) }}
|
||||||
</p>
|
</p>
|
||||||
<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]"
|
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]"
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svg
|
<!-- <svg
|
||||||
@click="sendReplay(item.id)"
|
@click="sendReplay(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]"
|
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"
|
viewBox="0 0 24 24"
|
||||||
@@ -145,7 +145,7 @@
|
|||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full md:w-[23.438vw] text-[#383E43]">
|
<div class="w-full md:w-[23.438vw] text-[#383E43]">
|
||||||
@@ -162,8 +162,8 @@
|
|||||||
<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
|
||||||
v-if="authUser?.avatarMedia"
|
v-if="authUser?.user.avatarMedia"
|
||||||
:src="authUser.avatarMedia"
|
:src="authUser.user.avatarMedia"
|
||||||
alt=""
|
alt=""
|
||||||
class="h-[8.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
class="h-[8.256vw0] md:h-[3.385vw] w-[10.256vw] md:w-[3.385vw] rounded-[50%]"
|
||||||
/>
|
/>
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
class="space-y-[2vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0"
|
class="space-y-[2vw] mt-[1vw] md:mt-0 ms-[1vw] md:ms-0 md:space-y-0"
|
||||||
>
|
>
|
||||||
<p class="text-[3.59vw] md:text-[0.938vw]">
|
<p class="text-[3.59vw] md:text-[0.938vw]">
|
||||||
{{ authUser?.name ? authUser.name : "کاربر مهمان" }}
|
{{ authUser?.user.name ? authUser.user.name : "کاربر مهمان" }}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
v-if="replayTarget === null"
|
v-if="replayTarget === null"
|
||||||
@@ -223,7 +223,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
if (process.client) {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
|
import {jDate} from "../../utils/jDate"
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const replayTarget = ref(null);
|
const replayTarget = ref(null);
|
||||||
@@ -235,13 +243,21 @@ const { data, refresh } = await useFetch("/api/productId", {
|
|||||||
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) => {
|
|
||||||
if (element.id === route.params.product) {
|
var ids = []
|
||||||
|
myCourses.data.value?.user.course.forEach((element) => {
|
||||||
|
ids.push(element.id)
|
||||||
|
|
||||||
|
|
||||||
|
if (ids.includes(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);
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,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]"
|
||||||
>
|
>
|
||||||
{{ myCourses.data.value.course.length }}
|
{{ myCourses.data.value.user.course.length }}
|
||||||
دوره
|
دوره
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
@@ -361,8 +361,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="authUser.user.avatarMedia"
|
||||||
:src="authUser.avatarMedia"
|
:src="authUser.user.avatarMedia"
|
||||||
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=""
|
||||||
/>
|
/>
|
||||||
@@ -376,12 +376,12 @@
|
|||||||
<p
|
<p
|
||||||
class="text-[4.038vw] md:text-[0.938vw] text-[#383E43] font-semibold mt-[1.25vw]"
|
class="text-[4.038vw] md:text-[0.938vw] text-[#383E43] font-semibold mt-[1.25vw]"
|
||||||
>
|
>
|
||||||
{{ authUser.name ? authUser.name : 'کاربر مهمان' }}
|
{{ authUser.user.name ? authUser.user.name : 'کاربر مهمان' }}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="font-[400] text-[3.19vw] md:text-[0.833vw] text-[#878787] mt-[0.417vw]"
|
class="font-[400] text-[3.19vw] md:text-[0.833vw] text-[#878787] mt-[0.417vw]"
|
||||||
>
|
>
|
||||||
{{ authUser.userName ? authUser.userName + '@' : 'نام کاربری'}}
|
{{ authUser.user.userName ? authUser.user.userName + '@' : 'نام کاربری'}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -521,12 +521,13 @@
|
|||||||
const tickets = await useFetch("/api/ticket/getTickets");
|
const tickets = await useFetch("/api/ticket/getTickets");
|
||||||
const lastTickets = tickets?.data?.value.result.slice(-2);
|
const lastTickets = tickets?.data?.value.result.slice(-2);
|
||||||
const myCourses = await useFetch("/api/auth/me");
|
const myCourses = await useFetch("/api/auth/me");
|
||||||
const lastCourses = myCourses.data?.value.course.slice(-2);
|
|
||||||
|
const lastCourses = myCourses.data?.value.com.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 today = new Date(); // تاریخ امروز
|
||||||
const pastDate = new Date(authUser.value.createdAt); // تاریخ گذشته
|
const pastDate = new Date(authUser.value.user.createdAt); // تاریخ گذشته
|
||||||
|
|
||||||
// تفاوت زمانی را محاسبه میکنیم
|
// تفاوت زمانی را محاسبه میکنیم
|
||||||
const timeDifference = today.getTime() - pastDate.getTime();
|
const timeDifference = today.getTime() - pastDate.getTime();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<tab :name=tab1>
|
<tab :name=tab1>
|
||||||
<div class="me-[4vw] grid grid-cols-1 md:grid-cols-3 mt-[6vw] md:mt-[1.25vw] gap-[1vw]">
|
<div class="me-[4vw] grid grid-cols-1 md:grid-cols-3 mt-[6vw] md:mt-[1.25vw] gap-[1vw]">
|
||||||
|
|
||||||
<div v-for="item in myCourses.data.value.course" :key="item.id">
|
<div v-for="item in myCourses.data.value.com" :key="item.id">
|
||||||
<ProgressCard :item="item"/>
|
<ProgressCard :item="item"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -13,14 +13,21 @@
|
|||||||
<tab :name=tab2>
|
<tab :name=tab2>
|
||||||
<div class="me-[4vw] grid grid-cols-1 md:grid-cols-3 mt-[6vw] md:mt-[1.25vw] gap-[1vw]">
|
<div class="me-[4vw] grid grid-cols-1 md:grid-cols-3 mt-[6vw] md:mt-[1.25vw] gap-[1vw]">
|
||||||
|
|
||||||
<div v-for="item in myCourses.data.value.course" :key="item.id">
|
<div v-for="item in myCourses.data.value.com" :key="item.id" v-show="item.completionPercentage < 99">
|
||||||
|
|
||||||
|
<ProgressCard :item="item"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</tab>
|
||||||
|
<tab :name=tab3>
|
||||||
|
<div class="me-[4vw] grid grid-cols-1 md:grid-cols-3 mt-[6vw] md:mt-[1.25vw] gap-[1vw]">
|
||||||
|
|
||||||
|
<div v-for="item in myCourses.data.value.com" :key="item.id" v-show="item.completionPercentage > 99">
|
||||||
|
|
||||||
<ProgressCard :item="item"/>
|
<ProgressCard :item="item"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</tab>
|
</tab>
|
||||||
<!-- <tab :name=tab3>
|
|
||||||
محتوا سوم
|
|
||||||
</tab> -->
|
|
||||||
<tab :name=tab4>
|
<tab :name=tab4>
|
||||||
|
|
||||||
</tab>
|
</tab>
|
||||||
|
|||||||
+11
-10
@@ -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="authUser.user.avatarMedia"
|
||||||
:src="authUser.avatarMedia"
|
:src="authUser.user.avatarMedia"
|
||||||
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"
|
||||||
/>
|
/>
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
:actions="false"
|
:actions="false"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="relative items-center gap-[5vw] md:gap-0 grid grid-cols-1 md:grid-cols-2 mt-[2vw] w-full md:w-[65%]"
|
class="relative items-center gap-[5vw] md:gap-0 grid grid-cols-1 md:grid-cols-2 mt-[2vw] w-full md:w-[65%] pb-[20vw] md:pb-0"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col space-y-[0.2vw] mb-[0.5vw]">
|
<div class="flex flex-col space-y-[0.2vw] mb-[0.5vw]">
|
||||||
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]"
|
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]"
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="name"
|
name="name"
|
||||||
:value="data?.phone"
|
:value="data?.user.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="data?.name"
|
:value="data?.user.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="data?.userName"
|
:value="data?.user.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,14 +130,14 @@
|
|||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="email"
|
name="email"
|
||||||
:value="data?.email"
|
:value="data?.user.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]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<FormKit
|
<FormKit
|
||||||
input-class="
|
input-class="
|
||||||
text-[3.59vw] md:text-[0.833vw] absolute md:left-[1vw] top-[80vw] md:top-[11vw] greenButton h-[13.59vw]
|
text-[3.59vw] md:text-[0.833vw] absolute md:left-[1vw] top-[100vw] md:top-[11vw] greenButton h-[13.59vw]
|
||||||
md:h-[2.813vw] w-full md:w-[8.438vw] rounded-[2.564vw] md:rounded-[0.521vw] flexBox px-0
|
md:h-[2.813vw] w-full md:w-[8.438vw] rounded-[2.564vw] md:rounded-[0.521vw] flexBox px-0
|
||||||
"
|
"
|
||||||
type="submit"
|
type="submit"
|
||||||
@@ -160,7 +160,8 @@ const loading = ref(false);
|
|||||||
const {data, refresh} = await useFetch('/api/auth/me')
|
const {data, refresh} = await useFetch('/api/auth/me')
|
||||||
|
|
||||||
const edit = async (formData) => {
|
const edit = async (formData) => {
|
||||||
authUser.value.name = formData.name
|
authUser.value.user.name = formData.name
|
||||||
|
authUser.value.user.userName = formData.userName
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
await $fetch("/api/user/update", {
|
await $fetch("/api/user/update", {
|
||||||
@@ -194,7 +195,7 @@ async function changePhoto(val) {
|
|||||||
avatarMedia: data.data.value.url
|
avatarMedia: data.data.value.url
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
authUser.value.avatarMedia = data.data.value.url
|
authUser.value.user.avatarMedia = data.data.value.url
|
||||||
// profileImage.value = data.data.value.url
|
// profileImage.value = data.data.value.url
|
||||||
toast.success('تصویر پروفایل تغییر کرد')
|
toast.success('تصویر پروفایل تغییر کرد')
|
||||||
refresh()
|
refresh()
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
<div class="basis-2/6 flex items-center justify-end gap-[1vw]">
|
<div class="basis-2/6 flex items-center justify-end gap-[1vw]">
|
||||||
<button
|
<button
|
||||||
@click="openTicket(ticket.id)"
|
@click="openTicket(ticket.id)"
|
||||||
class="hidden md:block text-[0.741vw] bg-[#F5F5F5] text-[#878787] h-[2.135vw] w-[3.646vw] rounded-[0.521vw]"
|
class="text-[2.5vw] md:text-[0.741vw] bg-[#F5F5F5] text-[#878787] h-[7vw] md:h-[2.135vw] w-[12vw] md:w-[3.646vw] rounded-[1vw] md:rounded-[0.521vw]"
|
||||||
>
|
>
|
||||||
مشاوره
|
مشاوره
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<li
|
<li
|
||||||
v-for="(item, index) in payments.data.value"
|
v-for="(item, index) in payments.data.value"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="flex justify-between items-center"
|
class="py-[2vw] border-b md:py-0 md:border-none 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]">
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
v-for="(item, index) in payments.data.value"
|
v-for="(item, index) in payments.data.value"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-show="item.reason === 'deposit'"
|
v-show="item.reason === 'deposit'"
|
||||||
class="flex justify-between items-center"
|
class="py-[2vw] border-b md:py-0 md:border-none 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 === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
{{ item.reason === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
v-for="(item, index) in payments.data.value"
|
v-for="(item, index) in payments.data.value"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-show="item.reason === 'withdrawal'"
|
v-show="item.reason === 'withdrawal'"
|
||||||
class="flex justify-between items-center"
|
class="py-[2vw] border-b md:py-0 md:border-none 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 === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
{{ item.reason === 'deposit' ? 'افزایش موجودی' : 'کاهش موجودی'}}
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<div class="pt-[10vw] md:pt-0 space-y-[3vw] md:space-y-[1vw]">
|
<div class="pt-[10vw] md:pt-0 space-y-[3vw] md:space-y-[1vw]">
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] text-[#383E43]">
|
<p class="text-[3.19vw] md:text-[0.833vw] text-[#383E43]">
|
||||||
مبلغ مورد نظر <span v-if="price > 0" class="text-[0.6vw] font-bold text-end">{{ numberFormat(price) }} تومان</span>
|
مبلغ مورد نظر <span v-if="price > 0" class="text-[2vw] md:text-[0.6vw] font-bold text-end">{{ numberFormat(price) }} تومان</span>
|
||||||
</p>
|
</p>
|
||||||
<input
|
<input
|
||||||
v-model="price"
|
v-model="price"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
||||||
let name = query.hasOwnProperty('name') ? `name=${query.name}` : '';
|
let name = query.hasOwnProperty('name') ? `name=${query.name}` : '';
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/course?${category}&${page}&pageSize=2&${price}&${name}`, {
|
const data = await $fetch(`${apiBase}/course?${category}&${page}&pageSize=100&${price}&${name}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
|
|
||||||
export default defineEventHandler(async (event) => {
|
export default defineEventHandler(async (event) => {
|
||||||
const { public: { apiBase } } = useRuntimeConfig();
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
const body = await readBody(event);
|
|
||||||
const token = getCookie(event, 'token');
|
const token = getCookie(event, 'token');
|
||||||
|
const query = getQuery(event);
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/course/${body.id}?userId=${body.userId}`, {
|
const data = await $fetch(`${apiBase}/course/${query.id}?userId=${query.userId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
console.log(data, 'setce');
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user