create searchBox section
This commit is contained in:
@@ -2,6 +2,23 @@
|
|||||||
|
|
||||||
<NuxtLoadingIndicator color="#ffbe33" :duration="1" :throttle="0"/>
|
<NuxtLoadingIndicator color="#ffbe33" :duration="1" :throttle="0"/>
|
||||||
<NuxtLayout />
|
<NuxtLayout />
|
||||||
|
<div @click="showSearchBox = false">
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
</div>
|
||||||
<NuxtLayout name="footer"/>
|
<NuxtLayout name="footer"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const showSearchBox = useState("showSearchBox");
|
||||||
|
watch(showSearchBox, ()=>{
|
||||||
|
if (process.client) {
|
||||||
|
if (showSearchBox.value === true) {
|
||||||
|
document.body.classList.add('overflow-hidden')
|
||||||
|
}else{
|
||||||
|
document.body.classList.remove('overflow-hidden')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
+2
-4
@@ -92,7 +92,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|
||||||
<NuxtLink :to="`${props.course?.id}`"
|
<NuxtLink :to="`${props.course?._id}`"
|
||||||
class="font-[500] mt-[0.5vw] flex items-center justify-center gap-[0.417vw] md:h-[2.292vw] px-[4.103vw] md:px-0 py-[2.308vw] md:py-[0.521vw] bg-primaryGreen text-white text-[3.19vw] md:text-[0.833vw] rounded-[2.564vw] md:rounded-[0.521vw] md:w-[7.917vw]">
|
class="font-[500] mt-[0.5vw] flex items-center justify-center gap-[0.417vw] md:h-[2.292vw] px-[4.103vw] md:px-0 py-[2.308vw] md:py-[0.521vw] bg-primaryGreen text-white text-[3.19vw] md:text-[0.833vw] rounded-[2.564vw] md:rounded-[0.521vw] md:w-[7.917vw]">
|
||||||
شروع دوره
|
شروع دوره
|
||||||
<svg
|
<svg
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="absolute top-[0.9vw] left-[0.9vw] text-[#383E43] font-bold thin text-[0.833vw]">{{props.course.satisfactionLevel}}</span>
|
<span class="absolute top-[0.9vw] w-[1.5vw] text-center left-[0.4vw] text-[#383E43] font-bold thin text-[0.833vw]">{{props.course.averageRating}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -141,9 +141,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
const props = defineProps(['course']);
|
const props = defineProps(['course']);
|
||||||
const MyArray = ['Salam','Man','Sadegh','Hastam'];
|
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
console.log(props);
|
|
||||||
function hideEndOfString(inputString) {
|
function hideEndOfString(inputString) {
|
||||||
const words = inputString.split(' ');
|
const words = inputString.split(' ');
|
||||||
if (words.length > 8) {
|
if (words.length > 8) {
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
<!-- comment 1 -->
|
<!-- comment 1 -->
|
||||||
<div
|
<div
|
||||||
class="relative bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw] flex justify-between p-[4vw] md:p-[1.55vw]"
|
v-for="item in props.props" :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
|
<img
|
||||||
src="/public/images/client1.png"
|
src="/public/images/client1.png"
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
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]">
|
<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]">
|
||||||
علی مصلحی
|
علی مصلحی
|
||||||
</p>
|
</p>
|
||||||
@@ -40,10 +41,8 @@
|
|||||||
<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]"
|
||||||
>
|
>
|
||||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با
|
{{ item.text }}
|
||||||
استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله
|
|
||||||
در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد
|
|
||||||
نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,7 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- comment 2 -->
|
<!-- comment 2 -->
|
||||||
<div
|
<!-- <div
|
||||||
class="mt-[4vw] md:mt-[1vw] bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw]"
|
class="mt-[4vw] md:mt-[1vw] bg-[#F8F8F8] rounded-[3.846vw] md:rounded-[0.781vw]"
|
||||||
>
|
>
|
||||||
<div class="flex justify-between relative p-[4vw] md:p-[1.55vw]">
|
<div class="flex justify-between relative p-[4vw] md:p-[1.55vw]">
|
||||||
@@ -179,5 +178,10 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps(['props'])
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -61,8 +61,9 @@
|
|||||||
class="mt-[3vw] md:mt-[0.7vw] h-[2.051vw] md:h-[0.521vw] rounded-[2vw] md:rounded-[0.521vw]"
|
class="mt-[3vw] md:mt-[0.7vw] h-[2.051vw] md:h-[0.521vw] rounded-[2vw] md:rounded-[0.521vw]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:class="`w-[${props.props.completionPercentage}%]`"
|
:class="`w-[${props.props.completionPercentage}%]`"
|
||||||
class=" rounded-[2vw] md:rounded-[0.521vw] h-[2.051vw] md:h-[0.521vw]"
|
|
||||||
|
class="rounded-[2vw] md:rounded-[0.521vw] h-[2.051vw] md:h-[0.521vw]"
|
||||||
>
|
>
|
||||||
<!-- {{props.props.completionPercentage}} -->
|
<!-- {{props.props.completionPercentage}} -->
|
||||||
</div>
|
</div>
|
||||||
@@ -74,6 +75,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const adad = 2;
|
const adad = 2;
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(['props'])
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#progressbar {
|
#progressbar {
|
||||||
@@ -84,7 +87,6 @@ const props = defineProps(['props'])
|
|||||||
#progressbar > div {
|
#progressbar > div {
|
||||||
background-color: #0d3f40;
|
background-color: #0d3f40;
|
||||||
float: left;
|
float: left;
|
||||||
|
|
||||||
left: 0;
|
left: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -7,18 +7,16 @@
|
|||||||
class="absolute h-[86.41vw] md:h-[40.625vw] top-0 left-0 w-full object-cover brightness-75"
|
class="absolute h-[86.41vw] md:h-[40.625vw] top-0 left-0 w-full object-cover brightness-75"
|
||||||
/>
|
/>
|
||||||
<div class="mt-[14vw] ms-[9.5vw] z-[1] text-white">
|
<div class="mt-[14vw] ms-[9.5vw] z-[1] text-white">
|
||||||
<h1
|
<h1 class="text-[5.751vw] md:text-[1.69vw] font-[600] -tracking-[0.05vw]">
|
||||||
class="text-[5.751vw] md:text-[1.69vw] font-[600] -tracking-[0.05vw]"
|
|
||||||
>
|
|
||||||
{{ props.props.name }}
|
{{ props.props.name }}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] mt-[0.6vw] text-[#E5E5E5]">
|
<p class="text-[3.19vw] md:text-[0.833vw] mt-[0.6vw] text-[#E5E5E5]">
|
||||||
{{props.props.categories[0].name}}
|
{{ props.props.categories[0].name }}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="hidden md:block w-[39.896vw] text-[1.055vw] leading-[1.582vw] mt-[1.2vw]"
|
class="hidden md:block w-[39.896vw] text-[1.055vw] leading-[1.582vw] mt-[1.2vw]"
|
||||||
>
|
>
|
||||||
{{props.props.description}}
|
{{ props.props.description }}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
class="text-[2.836vw] md:text-[0.741vw] text-[##E5E5E5] mt-[1.8vw] absolute bottom-[8vw] md:bottom-auto md:relative"
|
class="text-[2.836vw] md:text-[0.741vw] text-[##E5E5E5] mt-[1.8vw] absolute bottom-[8vw] md:bottom-auto md:relative"
|
||||||
@@ -115,7 +113,9 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<div class="space-y-[0.3vw]">
|
<div class="space-y-[0.3vw]">
|
||||||
<p class="text-[3.59vw] md:text-[1.055vw]">آخرین بروزرسانی</p>
|
<p class="text-[3.59vw] md:text-[1.055vw]">آخرین بروزرسانی</p>
|
||||||
<p class="text-[2.518vw] md:text-[0.741vw]">{{props.props.createdAt}}</p>
|
<p class="text-[2.518vw] md:text-[0.741vw]">
|
||||||
|
{{ shamsi[2] }} / {{ shamsi[1] }} / {{ shamsi[0] }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-l"></div>
|
<div class="border-l"></div>
|
||||||
@@ -144,7 +144,9 @@
|
|||||||
|
|
||||||
<div class="space-y-[0.3vw]">
|
<div class="space-y-[0.3vw]">
|
||||||
<p class="text-[3.59vw] md:text-[1.055vw]">مدت زمان دوره</p>
|
<p class="text-[3.59vw] md:text-[1.055vw]">مدت زمان دوره</p>
|
||||||
<p class="text-[2.518vw] md:text-[0.741vw]">{{props.props.duration}} ساعت</p>
|
<p class="text-[2.518vw] md:text-[0.741vw]">
|
||||||
|
{{ props.props.duration }} ساعت
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-l"></div>
|
<div class="border-l"></div>
|
||||||
@@ -186,7 +188,9 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div class="space-y-[0.3vw]">
|
<div class="space-y-[0.3vw]">
|
||||||
<p class="text-[3.59vw] md:text-[1.055vw]">{{props.props.studentsCount}}</p>
|
<p class="text-[3.59vw] md:text-[1.055vw]">
|
||||||
|
{{ props.props.studentsCount }}
|
||||||
|
</p>
|
||||||
<p class="text-[2.518vw] md:text-[0.741vw]">دانشجو</p>
|
<p class="text-[2.518vw] md:text-[0.741vw]">دانشجو</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,6 +200,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(["props"]);
|
||||||
|
const isoDateString = props.props.createdAt;
|
||||||
|
const dateObject = new Date(isoDateString);
|
||||||
|
const year = dateObject.getFullYear();
|
||||||
|
const month = dateObject.getMonth() + 1;
|
||||||
|
const day = dateObject.getDate();
|
||||||
|
const hours = dateObject.getHours();
|
||||||
|
const minutes = dateObject.getMinutes();
|
||||||
|
const seconds = dateObject.getSeconds();
|
||||||
|
|
||||||
|
|
||||||
|
const shamsi = gregorian_to_jalali(year,month,day)
|
||||||
</script>
|
</script>
|
||||||
@@ -19,17 +19,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-[6vw] md:mt-[2.1vw] space-y-[3vw] md:space-y-[1vw] thin">
|
<div class="mt-[6vw] md:mt-[2.1vw] space-y-[3vw] md:space-y-[1vw] thin">
|
||||||
<div
|
<div
|
||||||
class="px-[3vw] md:px-[0.4vw] flex items-center justify-between bg-[#F4FDFD] rounded-[3.846vw] md:rounded-[0.781vw] h-[15.385vw] md:h-[3.438vw] w-full smallShadow"
|
v-for="headline in props.props.courseHeadlines" :key="headline.id"
|
||||||
|
class="px-[3vw] md:px-[0.4vw] flex items-center bg-[#F4FDFD] rounded-[3.846vw] md:rounded-[0.781vw] h-[15.385vw] md:h-[3.438vw] w-full smallShadow"
|
||||||
>
|
>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative basis-5/6 md:basis-3/6 w-full">
|
||||||
<span
|
<span
|
||||||
class="borderb mx-[0.9vw] ps-[0.6vw] pe-[2.5vw] md:pe-[0.5vw] text-[4.038vw] md:text-[1.055vw] font-black text-[#878787]"
|
class=" border-b-[0.15vw] border-[#878787] px-[1vw] md:px-[0.5vw] ms-[0.3vw] me-[2vw] md:me-[0.5vw] text-[4.038vw] md:text-[1.055vw] font-black text-[#878787]"
|
||||||
>
|
>
|
||||||
1
|
{{ props.props.courseHeadlines.indexOf(headline)+1 }}
|
||||||
</span>
|
</span>
|
||||||
<h2 class="border-r ps-[2.2vw]">HTML چیست؟</h2>
|
<h2 class="border-r ps-[2.2vw]">{{ headline.headline }}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden md:flex items-center text-[0.833vw] ms-[2.5vw]">
|
|
||||||
|
|
||||||
|
<div class="hidden md:flex items-center text-[0.833vw] w-full md:basis-2/6">
|
||||||
<span>08:55</span>
|
<span>08:55</span>
|
||||||
<svg
|
<svg
|
||||||
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
||||||
@@ -54,97 +57,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-[1vw] pe-[1vw]">
|
<div class="flex gap-[1vw] basis-1/6 md:basis-1/6 w-full text-end justify-end md:pe-[2vw]">
|
||||||
<svg
|
|
||||||
class="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="M9 11V17L11 15"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M9 17L7 15"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22 10V15C22 20 20 22 15 22H9C4 22 2 20 2 15V9C2 4 4 2 9 2H14"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22 10H18C15 10 14 9 14 6V2L22 10Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<svg
|
|
||||||
class="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="M4 12V8.44002C4 4.02002 7.13 2.21002 10.96 4.42002L14.05 6.20002L17.14 7.98002C20.97 10.19 20.97 13.81 17.14 16.02L14.05 17.8L10.96 19.58C7.13 21.79 4 19.98 4 15.56V12Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="px-[3vw] md:px-[0.4vw] flex items-center justify-between bg-[#F4FDFD] rounded-[3.846vw] md:rounded-[0.781vw] h-[15.385vw] md:h-[3.438vw] w-full smallShadow"
|
|
||||||
>
|
|
||||||
<div class="flex items-center relative">
|
|
||||||
<span
|
|
||||||
class="borderb mx-[0.9vw] ps-[0.6vw] pe-[2.5vw] md:pe-[0.5vw] text-[4.038vw] md:text-[1.055vw] font-black text-[#878787]"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</span>
|
|
||||||
<h2 class="border-r ps-[2.2vw]">HTML چیست؟</h2>
|
|
||||||
</div>
|
|
||||||
<div class="hidden md:flex items-center text-[0.833vw] ms-[2.5vw]">
|
|
||||||
<span>08:55</span>
|
|
||||||
<svg
|
|
||||||
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M18.3332 9.99996C18.3332 14.6 14.5998 18.3333 9.99984 18.3333C5.39984 18.3333 1.6665 14.6 1.6665 9.99996C1.6665 5.39996 5.39984 1.66663 9.99984 1.66663C14.5998 1.66663 18.3332 5.39996 18.3332 9.99996Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M13.0919 12.65L10.5086 11.1083C10.0586 10.8416 9.69189 10.2 9.69189 9.67497V6.2583"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex gap-[1vw] pe-[1vw]">
|
|
||||||
<svg
|
<svg
|
||||||
class="h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
class="h-[4.615vw] w-[4.615vw] md:h-[1.25vw] md:w-[1.25vw]"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@@ -199,106 +112,52 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
|
||||||
class="px-[3vw] md:px-[0.4vw] flex items-center justify-between bg-[#F4FDFD] rounded-[3.846vw] md:rounded-[0.781vw] h-[15.385vw] md:h-[3.438vw] w-full smallShadow"
|
|
||||||
>
|
|
||||||
<div class="flex items-center relative">
|
|
||||||
<span
|
|
||||||
class="borderb mx-[0.9vw] ps-[0.6vw] pe-[2.5vw] md:pe-[0.5vw] text-[4.038vw] md:text-[1.055vw] font-black text-[#878787]"
|
|
||||||
>
|
|
||||||
1
|
|
||||||
</span>
|
|
||||||
<h2 class="border-r ps-[2.2vw]">HTML چیست؟</h2>
|
|
||||||
</div>
|
|
||||||
<div class="hidden md:flex items-center text-[0.833vw] ms-[2.5vw]">
|
|
||||||
<span>08:55</span>
|
|
||||||
<svg
|
|
||||||
class="ms-[0.3vw] h-[1.042vw] w-[1.042vw]"
|
|
||||||
viewBox="0 0 20 20"
|
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M18.3332 9.99996C18.3332 14.6 14.5998 18.3333 9.99984 18.3333C5.39984 18.3333 1.6665 14.6 1.6665 9.99996C1.6665 5.39996 5.39984 1.66663 9.99984 1.66663C14.5998 1.66663 18.3332 5.39996 18.3332 9.99996Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M13.0919 12.65L10.5086 11.1083C10.0586 10.8416 9.69189 10.2 9.69189 9.67497V6.2583"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex gap-[1vw] pe-[1vw]">
|
|
||||||
<svg
|
|
||||||
class="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="M9 11V17L11 15"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M9 17L7 15"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22 10V15C22 20 20 22 15 22H9C4 22 2 20 2 15V9C2 4 4 2 9 2H14"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
<path
|
|
||||||
d="M22 10H18C15 10 14 9 14 6V2L22 10Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<svg
|
|
||||||
class="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="M4 12V8.44002C4 4.02002 7.13 2.21002 10.96 4.42002L14.05 6.20002L17.14 7.98002C20.97 10.19 20.97 13.81 17.14 16.02L14.05 17.8L10.96 19.58C7.13 21.79 4 19.98 4 15.56V12Z"
|
|
||||||
stroke="#383E43"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke-miterlimit="10"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps(['props'])
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.borderb::before {
|
.borderb::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 1.1vw;
|
right: 1vw;
|
||||||
width: 1vw;
|
width: 1.5vw;
|
||||||
background: #878787;
|
background: #878787;
|
||||||
height: 0.208vw;
|
height: 0.208vw;
|
||||||
border-radius: 20vw;
|
border-radius: 20vw;
|
||||||
|
|||||||
+130
-23
@@ -76,7 +76,11 @@
|
|||||||
<div
|
<div
|
||||||
class="relative navigator flexBox gap-[2.2vw] text-[0.938vw] text-[#383E43] font-medium"
|
class="relative navigator flexBox gap-[2.2vw] text-[0.938vw] text-[#383E43] font-medium"
|
||||||
>
|
>
|
||||||
<div id="searchBox" class="hidden absolute right-0 w-full">
|
<div
|
||||||
|
v-if="showSearchBox"
|
||||||
|
id="searchBox"
|
||||||
|
class="absolute right-0 w-full"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
class="h-[1.406vw] w-[1.406vw] absolute top-[0.5vw] right-[1vw]"
|
class="h-[1.406vw] w-[1.406vw] absolute top-[0.5vw] right-[1vw]"
|
||||||
viewBox="0 0 26 27"
|
viewBox="0 0 26 27"
|
||||||
@@ -100,14 +104,21 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
autofocus
|
||||||
|
id="searchElement"
|
||||||
|
v-model="search"
|
||||||
|
@click="logClick(true)"
|
||||||
|
@blur="logClick(false)"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="نام آموزش، دوره و... را وارد کنید"
|
placeholder="نام آموزش، دوره و... را وارد کنید"
|
||||||
class="thin w-full h-[2.604vw] rounded-[0.521vw] bg-[#F5F5F5] text-[#878787] text-[0.658vw] ps-[3vw]"
|
class="thin w-full h-[2.604vw] rounded-[0.521vw] bg-[#F5F5F5] text-[#878787] text-[0.658vw] ps-[3vw]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
<div class="border-e pe-[0.8vw] cursor-pointer" @click="openSearchBox">
|
class="border-e pe-[0.8vw] cursor-pointer"
|
||||||
|
@click="openSearchBox"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
width="1.458vw"
|
width="1.458vw"
|
||||||
height="1.406vw"
|
height="1.406vw"
|
||||||
@@ -182,7 +193,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/courses">
|
<nuxt-link to="/courses">
|
||||||
<span class="flexBox gap-[0.6vw]"
|
<span
|
||||||
|
class="flexBox gap-[0.6vw]"
|
||||||
:class="{ 'text-primaryGreen': $route.path === '/courses' }"
|
:class="{ 'text-primaryGreen': $route.path === '/courses' }"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -219,11 +231,10 @@
|
|||||||
</svg>
|
</svg>
|
||||||
دوره های آموزشی
|
دوره های آموزشی
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
<nuxt-link to="/about-us"
|
<nuxt-link to="/about-us">
|
||||||
>
|
<span
|
||||||
<span class="flexBox gap-[0.6vw]"
|
class="flexBox gap-[0.6vw]"
|
||||||
:class="{ 'text-primaryGreen': $route.path === '/about-us' }"
|
:class="{ 'text-primaryGreen': $route.path === '/about-us' }"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -234,7 +245,9 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
:class="{ 'stroke-primaryGreen': $route.path === '/about-us' }"
|
:class="{
|
||||||
|
'stroke-primaryGreen': $route.path === '/about-us',
|
||||||
|
}"
|
||||||
d="M12.5 22.5C18 22.5 22.5 18 22.5 12.5C22.5 7 18 2.5 12.5 2.5C7 2.5 2.5 7 2.5 12.5C2.5 18 7 22.5 12.5 22.5Z"
|
d="M12.5 22.5C18 22.5 22.5 18 22.5 12.5C22.5 7 18 2.5 12.5 2.5C7 2.5 2.5 7 2.5 12.5C2.5 18 7 22.5 12.5 22.5Z"
|
||||||
stroke="#383E43"
|
stroke="#383E43"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
@@ -242,7 +255,9 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
:class="{ 'stroke-primaryGreen': $route.path === '/about-us' }"
|
:class="{
|
||||||
|
'stroke-primaryGreen': $route.path === '/about-us',
|
||||||
|
}"
|
||||||
d="M12.5 8.5V13.5"
|
d="M12.5 8.5V13.5"
|
||||||
stroke="#383E43"
|
stroke="#383E43"
|
||||||
stroke-width="1.5"
|
stroke-width="1.5"
|
||||||
@@ -250,7 +265,9 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
<path
|
<path
|
||||||
:class="{ 'stroke-primaryGreen': $route.path === '/about-us' }"
|
:class="{
|
||||||
|
'stroke-primaryGreen': $route.path === '/about-us',
|
||||||
|
}"
|
||||||
d="M12.4946 16.5H12.5036"
|
d="M12.4946 16.5H12.5036"
|
||||||
stroke="#383E43"
|
stroke="#383E43"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
@@ -266,7 +283,7 @@
|
|||||||
|
|
||||||
<nuxt-link to="/account" v-if="authUser">
|
<nuxt-link to="/account" v-if="authUser">
|
||||||
<img
|
<img
|
||||||
src="/images/Profile.png"
|
:src="authUser?.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]"
|
||||||
/>
|
/>
|
||||||
@@ -274,28 +291,118 @@
|
|||||||
<nuxt-link to="/login" v-else>
|
<nuxt-link to="/login" v-else>
|
||||||
<svg
|
<svg
|
||||||
class="h-[3.698vw] w-[3.698vw] rounded-full p-[0.521vw]"
|
class="h-[3.698vw] w-[3.698vw] rounded-full p-[0.521vw]"
|
||||||
viewBox="0 0 27 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
viewBox="0 0 27 27"
|
||||||
<path opacity="0.4" d="M13.5 2.25C10.5525 2.25 8.15625 4.64625 8.15625 7.59375C8.15625 10.485 10.4175 12.825 13.365 12.9262C13.455 12.915 13.545 12.915 13.6125 12.9262C13.635 12.9262 13.6462 12.9262 13.6687 12.9262C13.68 12.9262 13.68 12.9262 13.6912 12.9262C16.5712 12.825 18.8325 10.485 18.8437 7.59375C18.8437 4.64625 16.4475 2.25 13.5 2.25Z" fill="#878787"/>
|
fill="none"
|
||||||
<path d="M19.2151 15.9187C16.0763 13.8262 10.9576 13.8262 7.79633 15.9187C6.36758 16.875 5.58008 18.1687 5.58008 19.5525C5.58008 20.9362 6.36758 22.2187 7.78508 23.1637C9.36008 24.2212 11.4301 24.75 13.5001 24.75C15.5701 24.75 17.6401 24.2212 19.2151 23.1637C20.6326 22.2075 21.4201 20.925 21.4201 19.53C21.4088 18.1462 20.6326 16.8637 19.2151 15.9187Z" fill="#878787"/>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
opacity="0.4"
|
||||||
|
d="M13.5 2.25C10.5525 2.25 8.15625 4.64625 8.15625 7.59375C8.15625 10.485 10.4175 12.825 13.365 12.9262C13.455 12.915 13.545 12.915 13.6125 12.9262C13.635 12.9262 13.6462 12.9262 13.6687 12.9262C13.68 12.9262 13.68 12.9262 13.6912 12.9262C16.5712 12.825 18.8325 10.485 18.8437 7.59375C18.8437 4.64625 16.4475 2.25 13.5 2.25Z"
|
||||||
|
fill="#878787"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M19.2151 15.9187C16.0763 13.8262 10.9576 13.8262 7.79633 15.9187C6.36758 16.875 5.58008 18.1687 5.58008 19.5525C5.58008 20.9362 6.36758 22.2187 7.78508 23.1637C9.36008 24.2212 11.4301 24.75 13.5001 24.75C15.5701 24.75 17.6401 24.2212 19.2151 23.1637C20.6326 22.2075 21.4201 20.925 21.4201 19.53C21.4088 18.1462 20.6326 16.8637 19.2151 15.9187Z"
|
||||||
|
fill="#878787"
|
||||||
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
<div
|
||||||
|
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"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="text-[0.vw] w-full text-end pe-[0.8vw] cursor-pointer"
|
||||||
|
@click="closeSearchBox"
|
||||||
|
>بستن</span
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="flexBox mt-[1vw] text-[0.8vw]" v-if="search?.length < 3">
|
||||||
|
برای جستجو حداقل 3 کلمه وارد کنید...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
<p v-if="data.courses.length < 1" class="flexBox mt-[1vw] text-[0.8vw]">
|
||||||
|
دوره ای یافت نشد !!!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div v-else class="cursor-pointer px-[1vw] pt-[2vw] space-y-[1.5vw]">
|
||||||
|
<div
|
||||||
|
@click="goToCourse(item?._id)"
|
||||||
|
v-for="item in data.courses"
|
||||||
|
:key="item.id"
|
||||||
|
class="flex justify-between items-center"
|
||||||
|
>
|
||||||
|
<div class="flex gap-[0.5vw]">
|
||||||
|
<img :src="item.image" alt="" class="h-[2.5vw] rounded-[0.2vw]" />
|
||||||
|
<div>
|
||||||
|
<p class="text-[0.8vw]">
|
||||||
|
{{ item.name }}
|
||||||
|
</p>
|
||||||
|
<p class="text-[0.6vw]">{{ item.categories[0].name }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p class="text-[0.7vw]">مشاهده دوره</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div v-for="item in data.courses" :key="item.id">{{ item.name }}</div> -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
const openSearchBox = () =>{
|
const showSearchBox = useState("showSearchBox", () => false);
|
||||||
|
const search = ref(null);
|
||||||
|
const openSearchBox = () => {
|
||||||
|
search.value = "";
|
||||||
|
showSearchBox.value = true;
|
||||||
if (process.client) {
|
if (process.client) {
|
||||||
document.getElementById('searchBox').classList.add('!block')
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
const router = useRouter();
|
||||||
|
const goToCourse = (val) =>{
|
||||||
|
router.push({
|
||||||
|
path: `/${val}`,
|
||||||
|
});
|
||||||
|
showSearchBox.value = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
const closeSearchBox = () => {
|
||||||
|
showSearchBox.value = false;
|
||||||
|
if (process.client) {
|
||||||
|
document.body.classList.remove("overflow-hidden");
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
};
|
||||||
})
|
|
||||||
|
const query = ref({});
|
||||||
|
const { data, refresh, pending } = await useFetch(() => "/api/course", {
|
||||||
|
method: "POST",
|
||||||
|
query: query,
|
||||||
|
});
|
||||||
|
watch(search, () => {
|
||||||
|
query.value = { name: search.value };
|
||||||
|
refresh();
|
||||||
|
console.log("data", data.value.courses.length);
|
||||||
|
//// console.log(search.value.length);
|
||||||
|
});
|
||||||
|
// watch(showSearchBox.value === false, () =>{
|
||||||
|
// // showSearchBox.value = null
|
||||||
|
// console.log('s');
|
||||||
|
// })
|
||||||
|
|
||||||
|
// function logClick(isInside) {
|
||||||
|
// if (isInside) {
|
||||||
|
// console.log("لاگ صحیح: داخل input کلیک شد.");
|
||||||
|
// } else {
|
||||||
|
// showSearchBox.value = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
</script>
|
</script>
|
||||||
+4
-1
@@ -10,8 +10,9 @@ export default defineNuxtConfig({
|
|||||||
'@nuxtjs/tailwindcss',
|
'@nuxtjs/tailwindcss',
|
||||||
'@nuxt/image',
|
'@nuxt/image',
|
||||||
'vue3-carousel-nuxt',
|
'vue3-carousel-nuxt',
|
||||||
"@formkit/nuxt"
|
"@formkit/nuxt",
|
||||||
],
|
],
|
||||||
|
|
||||||
tailwindcss: {
|
tailwindcss: {
|
||||||
cssPath: '~/assets/css/tailwind.css',
|
cssPath: '~/assets/css/tailwind.css',
|
||||||
configPath: '~/tailwind.config.js',
|
configPath: '~/tailwind.config.js',
|
||||||
@@ -19,5 +20,7 @@ export default defineNuxtConfig({
|
|||||||
|
|
||||||
build: {
|
build: {
|
||||||
transpile: ["vue-toastification"],
|
transpile: ["vue-toastification"],
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -5,10 +5,17 @@
|
|||||||
"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",
|
||||||
"generate": "nuxt generate",
|
"generate": "nuxt generate",
|
||||||
"preview": "nuxt preview",
|
"preview": "nuxt preview",
|
||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@formkit/nuxt": "^1.6.5",
|
"@formkit/nuxt": "^1.6.5",
|
||||||
"@nuxt/image": "^1.7.0",
|
"@nuxt/image": "^1.7.0",
|
||||||
|
|||||||
+219
-8
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center flex-col pb-[30vw] md:pb-[7vw]">
|
<div class="flex items-center flex-col pb-[30vw] md:pb-[7vw]">
|
||||||
<product-page-course-detailsHeader :props="data.course"/>
|
<product-page-course-detailsHeader :props="data.course" />
|
||||||
<div
|
<div
|
||||||
class="flex flex-col flex-col-reverse md:flex-row justify-between w-[87.69%] md:w-[81.04%] mt-[10vw] md:mt-[4.7vw]"
|
class="flex flex-col flex-col-reverse md:flex-row justify-between w-[87.69%] md:w-[81.04%] mt-[10vw] md:mt-[4.7vw]"
|
||||||
>
|
>
|
||||||
@@ -8,25 +8,236 @@
|
|||||||
class="w-full md:w-[56.354vw] text-[#383E43] text-[3.59vw] md:text-[1.055vw] leading-[5.897vw] md:leading-[1.582vw]"
|
class="w-full md:w-[56.354vw] text-[#383E43] text-[3.59vw] md:text-[1.055vw] leading-[5.897vw] md:leading-[1.582vw]"
|
||||||
>
|
>
|
||||||
<product-page-course-detailsDescription :props="data.course" />
|
<product-page-course-detailsDescription :props="data.course" />
|
||||||
<product-page-course-detailsHeadlines :props="data.course"/>
|
test
|
||||||
<product-page-course-detailsComments :props="data.course"/>
|
<product-page-course-detailsHeadlines :props="data.course" />
|
||||||
|
|
||||||
|
<!-- <product-page-course-detailsComments :props="data.comments" /> -->
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-[3vw] md:gap-[0.7vw] mt-[12vw] md:mt-[6.3vw] mb-[6vw] md:mb-[2.1vw]"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="w-[1.538vw] md:w-[0.521vw] h-[8.462vw] md:h-[2.76vw]"
|
||||||
|
viewBox="0 0 10 53"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M0 5C0 2.23858 2.23858 0 5 0H10V53H5C2.23858 53 0 50.7614 0 48V5Z"
|
||||||
|
fill="#0D3F40"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<span class="text-[4.544vw] md:text-[1.481vw] font-semibold"
|
||||||
|
>نظرات</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- comment 1 -->
|
||||||
|
<div
|
||||||
|
v-for="item in data.comments"
|
||||||
|
: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
|
||||||
|
src="/public/images/client1.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]">
|
||||||
|
علی مصلحی
|
||||||
|
</p>
|
||||||
|
<div class="thin">
|
||||||
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
|
1402/09/14
|
||||||
|
</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
|
||||||
|
v-for="reply in item.replies"
|
||||||
|
: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]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="/public/images/client3.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]">
|
||||||
|
علی مصلحی
|
||||||
|
</p>
|
||||||
|
<div class="thin">
|
||||||
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
|
1402/09/14
|
||||||
|
</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]"
|
||||||
|
>
|
||||||
|
{{ reply.text }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <svg
|
||||||
|
@click="sendReplay(reply.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>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
@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]"
|
||||||
|
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>
|
</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"/>
|
<product-page-course-detailsCourse-information :props="data.course" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="w-[63.438vw] 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="flex gap-[1vw]">
|
||||||
|
<img
|
||||||
|
src="/public/images/client1.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]">علی مصلحی</p>
|
||||||
|
<p
|
||||||
|
v-if="replayTarget === null"
|
||||||
|
class="text-[2.836vw] md:text-[0.741vw] text-[#878787]"
|
||||||
|
>
|
||||||
|
پرسش جدید
|
||||||
|
</p>
|
||||||
|
<p v-else class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
|
پاسخ به علی مصلحی
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<textarea
|
||||||
|
v-model="comment"
|
||||||
|
class="h-[50vw] md:h-[18vw] w-full rounded-[3.846vw] md:rounded-[0.781vw] p-[1vw]"
|
||||||
|
name=""
|
||||||
|
id=""
|
||||||
|
cols="30"
|
||||||
|
rows="10"
|
||||||
|
></textarea>
|
||||||
|
<div
|
||||||
|
class="flex justify-end gap-[1vw] text-[3.19vw] md:text-[0.833vw] text-white"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
@click="deleteComment"
|
||||||
|
class="h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-[#5A6268]"
|
||||||
|
>
|
||||||
|
حذف
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="sendComment"
|
||||||
|
class="cursor-pointer h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-primaryGreen"
|
||||||
|
>
|
||||||
|
ثبت
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { useToast } from "vue-toastification";
|
||||||
|
const toast = useToast();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const {data} = await useFetch("/api/productId", {
|
const replayTarget = ref(null);
|
||||||
|
const { data, refresh } = await useFetch("/api/productId", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
id: route.params.product,
|
id: route.params.product,
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
console.log(data.value.course);
|
console.log(data.value.comments[0]);
|
||||||
|
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>
|
</script>
|
||||||
+63
-20
@@ -1,11 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<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
|
||||||
src="/public/images/client3.png"
|
:src="authUser?.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=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
|
<label for="file-upload" class="custom-file-upload">
|
||||||
<svg
|
<svg
|
||||||
class="h-[10.769vw] md:h-[2.188vw] w-[10.769vw] md:w-[2.188vw] absolute -bottom-[0.2vw] right-[4vw] md:right-[0.7vw]"
|
class="h-[10.769vw] md:h-[2.188vw] w-[10.769vw] md:w-[2.188vw] absolute -bottom-[0.2vw] right-[4vw] md:right-[0.7vw]"
|
||||||
viewBox="0 0 42 42"
|
viewBox="0 0 42 42"
|
||||||
@@ -70,12 +72,27 @@
|
|||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
</label>
|
||||||
|
<input type="file" id="file-upload" @change="changePhoto" />
|
||||||
</div>
|
</div>
|
||||||
<FormKit type="form" @submit="edit" :incomplete-message="false" :actions="false">
|
|
||||||
<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%]">
|
|
||||||
|
<FormKit
|
||||||
|
type="form"
|
||||||
|
@submit="edit"
|
||||||
|
:incomplete-message="false"
|
||||||
|
:actions="false"
|
||||||
|
>
|
||||||
|
<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%]"
|
||||||
|
>
|
||||||
<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>
|
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]"
|
||||||
<input type="text" name="name"
|
>شماره موبایل</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
:value="authUser?.phone"
|
:value="authUser?.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]"
|
||||||
@@ -93,7 +110,9 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-[0.2vw]">
|
<div class="flex flex-col space-y-[0.2vw]">
|
||||||
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]">نام کاربری</label>
|
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]"
|
||||||
|
>نام کاربری</label
|
||||||
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="userName"
|
name="userName"
|
||||||
:value="authUser?.userName"
|
:value="authUser?.userName"
|
||||||
@@ -102,7 +121,9 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-[0.2vw]">
|
<div class="flex flex-col space-y-[0.2vw]">
|
||||||
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]">ایمیل</label>
|
<label for="" class="text-[3.19vw] md:text-[0.833vw] font-[400]"
|
||||||
|
>ایمیل</label
|
||||||
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
name="email"
|
name="email"
|
||||||
:value="authUser?.email"
|
:value="authUser?.email"
|
||||||
@@ -115,7 +136,8 @@
|
|||||||
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-[80vw] 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"
|
||||||
|
>
|
||||||
ویرایش
|
ویرایش
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,24 +147,45 @@
|
|||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
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 edit = async (formData) => {
|
||||||
const edit = async(formData) => {
|
|
||||||
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()
|
location.reload();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error)
|
toast.error(error);
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
const changePhoto = async (val) => {
|
||||||
|
const fd = new FormData('hi')
|
||||||
|
fd.append('name', 'hi')
|
||||||
|
console.log('fd', fd);
|
||||||
|
// const data = await useFetch("/api/uploader", {
|
||||||
|
// method: "POST",
|
||||||
|
// body: {
|
||||||
|
// file: val.target.value,
|
||||||
|
// directoryName: "profileAvatar",
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// console.log("done", data);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
input[type="file"] {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
.custom-file-upload {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
+59
-13
@@ -17,20 +17,28 @@
|
|||||||
<div class="flex flex-col flex-col-reverse pb-[10vw]">
|
<div class="flex flex-col flex-col-reverse pb-[10vw]">
|
||||||
<ul
|
<ul
|
||||||
class="space-y-[2vw] md:space-y-[0.5vw] mt-[0.5vw] border-b"
|
class="space-y-[2vw] md:space-y-[0.5vw] mt-[0.5vw] border-b"
|
||||||
v-for="ticket in tickets"
|
v-for="(ticket, index) in tickets"
|
||||||
:key="ticket.id"
|
:key="ticket.id"
|
||||||
>
|
>
|
||||||
|
|
||||||
<li class="flex justify-between items-center pt-[1.5vw] md:pt-0">
|
<li class="flex justify-between pt-[1.5vw] md:pt-0">
|
||||||
|
|
||||||
|
|
||||||
<p
|
<p
|
||||||
@click="openTicket(ticket.id)"
|
@click="openTicket(ticket.id)"
|
||||||
class="text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
class="basis-2/6 text-[3.59vw] md:text-[0.938vw] text-[#383E43]">
|
||||||
{{ ticket.subject }}
|
{{ ticket.subject }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] text-[#878787]">
|
|
||||||
{{ ticket.createdAt }}
|
|
||||||
|
<p class="basis-2/6 flexBox relative text-[3.19vw] md:text-[0.833vw] text-[#878787]">
|
||||||
|
<span v-show="num === index"
|
||||||
|
v-for="(item, num) in jalali" :key="num"
|
||||||
|
>{{item[2]}} / {{item[1]}} / {{item[0]}}</span>
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center 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="hidden md:block text-[0.741vw] bg-[#F5F5F5] text-[#878787] h-[2.135vw] w-[3.646vw] rounded-[0.521vw]"
|
||||||
@@ -52,7 +60,7 @@
|
|||||||
<div class="flex flex-col flex-col-reverse">
|
<div class="flex flex-col flex-col-reverse">
|
||||||
<div v-if="loading" class="loadingText">درحال دریافت اطلاعات...</div>
|
<div v-if="loading" class="loadingText">درحال دریافت اطلاعات...</div>
|
||||||
<div
|
<div
|
||||||
class="justify-self-start mt-[5vw] md:mt-0"
|
class="grid mt-[5vw] md:mt-0"
|
||||||
v-for="(message, index) in ticketMessages[0]
|
v-for="(message, index) in ticketMessages[0]
|
||||||
?.ticketMessages"
|
?.ticketMessages"
|
||||||
:key="index"
|
:key="index"
|
||||||
@@ -60,13 +68,20 @@
|
|||||||
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="rounded-b-[5.128vw] md:rounded-b-[1.042vw] rounded-l-[5.128vw] md:rounded-l-[1.042vw] w-[80vw] md:w-[40vw] p-[4vw] md:p-[2vw] bg-[#F8F8F8] mb-[1vw] text-[#383E43]"
|
class="justify-self-start rounded-b-[5.128vw] md:rounded-b-[1.042vw] rounded-l-[5.128vw] md:rounded-l-[1.042vw] w-[80vw] md:w-[40vw] p-[4vw] md:p-[2vw] bg-[#F8F8F8] mb-[1vw] text-[#383E43]"
|
||||||
|
:class="{ 'justify-self-end rounded-b-[5.128vw] md:rounded-b-[1.042vw] rounded-l-[5.128vw] md:rounded-l-[1.042vw] w-[80vw] md:w-[40vw] p-[4vw] md:p-[2vw] !bg-[#F4FDFD] mb-[1vw] text-[#383E43]' : message.createdBy.roles[0] === 'Admin' }"
|
||||||
|
|
||||||
>
|
>
|
||||||
<p class="text-[3.59vw] md:text-[1.055vw]">
|
<p class="text-[3.59vw] md:text-[1.055vw]">
|
||||||
{{ message.createdBy && "کاربر مهمان" }}
|
{{ message.createdBy && "کاربر مهمان" }} {{ }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[#878787] text-[2.836vw] md:text-[0.741vw] mt-[0.5vw]">
|
<!-- <p class="text-[#878787] text-[2.836vw] md:text-[0.741vw] mt-[0.5vw]">
|
||||||
{{ message.createdAt }}
|
{{ message.createdAt }}
|
||||||
|
</p> -->
|
||||||
|
<p class="text-[#878787] text-[2.836vw] md:text-[0.741vw] mt-[0.5vw]">
|
||||||
|
<span v-show="num === index"
|
||||||
|
v-for="(item, num) in jalali" :key="num"
|
||||||
|
>{{item[2]}} / {{item[1]}} / {{item[0]}}</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] mt-[5vw] md:mt-[2vw]">
|
<p class="text-[3.19vw] md:text-[0.833vw] mt-[5vw] md:mt-[2vw]">
|
||||||
{{ message.content }}
|
{{ message.content }}
|
||||||
@@ -252,6 +267,7 @@
|
|||||||
<p class="text-[3.59vw] md:text-[1.055vw]">
|
<p class="text-[3.59vw] md:text-[1.055vw]">
|
||||||
{{ message.createdBy && "کاربر مهمان" }}
|
{{ message.createdBy && "کاربر مهمان" }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="text-[#878787] text-[2.836vw] md:text-[0.741vw] mt-[0.5vw]">
|
<p class="text-[#878787] text-[2.836vw] md:text-[0.741vw] mt-[0.5vw]">
|
||||||
{{ message.createdAt }}
|
{{ message.createdAt }}
|
||||||
</p>
|
</p>
|
||||||
@@ -365,6 +381,35 @@ const subject = ref(null);
|
|||||||
const content = ref(null);
|
const content = ref(null);
|
||||||
const ticketMessages = ref([]);
|
const ticketMessages = ref([]);
|
||||||
const update = ref(null)
|
const update = ref(null)
|
||||||
|
const day = ref([])
|
||||||
|
const month = ref([])
|
||||||
|
const year = ref([])
|
||||||
|
const shamsi = ref([])
|
||||||
|
|
||||||
|
tickets.value.map(item =>{
|
||||||
|
item = new Date(item.createdAt)
|
||||||
|
year.value.push(item.getFullYear())
|
||||||
|
month.value.push(item.getMonth() + 1)
|
||||||
|
day.value.push(item.getDate())
|
||||||
|
})
|
||||||
|
|
||||||
|
const combinedItems = year.value.map((year, index) => ({
|
||||||
|
year,
|
||||||
|
month: month.value[index],
|
||||||
|
day: day.value[index],
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
const values = combinedItems.map(item =>(
|
||||||
|
Object.values(item)
|
||||||
|
))
|
||||||
|
const jalali = ref([])
|
||||||
|
const shamsis = values.map(item => (
|
||||||
|
jalali.value.push(gregorian_to_jalali(item[0],item[1],item[2]))
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const sendTicket = async () => {
|
const sendTicket = async () => {
|
||||||
@@ -377,9 +422,10 @@ const sendTicket = async () => {
|
|||||||
subject: subject.value,
|
subject: subject.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
load()
|
// load()
|
||||||
addTicketForm.value = false;
|
addTicketForm.value = false;
|
||||||
subject.value = null;
|
subject.value = null;
|
||||||
|
location.reload()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -390,7 +436,7 @@ const openTicket = async (data) => {
|
|||||||
const slides = document.getElementsByClassName("close");
|
const slides = document.getElementsByClassName("close");
|
||||||
for (let i = 0; i < slides.length; i++) {
|
for (let i = 0; i < slides.length; i++) {
|
||||||
if (slides[i].id === data) {
|
if (slides[i].id === data) {
|
||||||
slides[i].style.maxHeight = (slides[i].scrollHeight * 2) + "px";
|
slides[i].style.maxHeight = slides[i].scrollHeight + "vh";
|
||||||
} else {
|
} else {
|
||||||
slides[i].style.maxHeight = null;
|
slides[i].style.maxHeight = null;
|
||||||
}
|
}
|
||||||
@@ -406,7 +452,6 @@ const openTicket = async (data) => {
|
|||||||
ticketMessages.value.push(single.value);
|
ticketMessages.value.push(single.value);
|
||||||
reload()
|
reload()
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
const sendMessage = async (data, reload) => {
|
const sendMessage = async (data, reload) => {
|
||||||
if (content.value === null || '') {
|
if (content.value === null || '') {
|
||||||
@@ -424,6 +469,7 @@ const sendMessage = async (data, reload) => {
|
|||||||
openTicket().reload()
|
openTicket().reload()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const tab1 = `<p class="flex items-center gap-[0.5vw] p-[2vw] md:p-0 md:px-[0.6vw] rounded-[2.564vw]">
|
const tab1 = `<p class="flex items-center gap-[0.5vw] p-[2vw] md:p-0 md:px-[0.6vw] rounded-[2.564vw]">
|
||||||
<svg
|
<svg
|
||||||
class="hidden md:block w-[1.406vw] h-[1.406vw]"
|
class="hidden md:block w-[1.406vw] h-[1.406vw]"
|
||||||
|
|||||||
@@ -51,15 +51,15 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<p class="w-full text-end text-[4.544vw] md:text-[1.055vw]">
|
<p class="w-full text-end text-[4.544vw] md:text-[1.055vw]">
|
||||||
60,000
|
{{ data }},000
|
||||||
<span class="text-[2.836vw] md:text-[0.741vw] font-[400]">
|
<span class="text-[2.836vw] md:text-[0.741vw] font-[400]">
|
||||||
تومان
|
تومان
|
||||||
</span>
|
</span>
|
||||||
</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>
|
<p class="text-[3.19vw] md:text-[0.833vw] text-[#383E43]">مبلغ مورد نظر</p>
|
||||||
<input type="number" placeholder="تومان" class="text-[2.836vw] md:text-[0.741vw] h-[13.59vw] md:h-[2.969vw] w-full rounded-[2.564vw] md:rounded-[0.521vw] bg-[#F5F5F5] ps-[4vw] md:ps-[1vw]">
|
<input v-model="price" type="number" placeholder="تومان" class="text-[2.836vw] md:text-[0.741vw] h-[13.59vw] md:h-[2.969vw] w-full rounded-[2.564vw] md:rounded-[0.521vw] bg-[#F5F5F5] ps-[4vw] md:ps-[1vw]">
|
||||||
<button class="text-[3.59vw] md:text-[0.938vw] greenButton text-center h-[11.538vw] md:h-[2.969vw] w-full rounded-[2.564vw] md:rounded-[0.521vw]">شارژ حساب</button>
|
<button @click="charge" class="text-[3.59vw] md:text-[0.938vw] greenButton text-center h-[11.538vw] md:h-[2.969vw] w-full rounded-[2.564vw] md:rounded-[0.521vw]">شارژ حساب</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,6 +79,35 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {Tabs, Tab} from 'vue3-tabs-component';
|
import {Tabs, Tab} from 'vue3-tabs-component';
|
||||||
|
|
||||||
|
const {data, refresh} = await useFetch('/api/user/balance')
|
||||||
|
const price = ref(null)
|
||||||
|
const charge = async () =>{
|
||||||
|
console.log(price.value);
|
||||||
|
const toPay = await useFetch("/api/user/add", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
amount: price.value,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
refresh()
|
||||||
|
price.value = null
|
||||||
|
console.log(toPay);
|
||||||
|
}
|
||||||
|
console.log('wallet,' , data.value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const tab1 =
|
const tab1 =
|
||||||
`<p
|
`<p
|
||||||
class="flex items-center gap-[0.5vw] p-[2vw] md:p-0 md:px-[0.6vw] rounded-[2.564vw]">
|
class="flex items-center gap-[0.5vw] p-[2vw] md:p-0 md:px-[0.6vw] rounded-[2.564vw]">
|
||||||
|
|||||||
+30
-4
@@ -61,6 +61,8 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
|
v-model="search"
|
||||||
|
@change="searchHandler"
|
||||||
class="thin w-[100%] md:w-[45vw] h-[10.769vw] md:h-[3.333vw] text-[2.836vw] md:text-[0.741vw] text-[#878787] rounded-[2.564vw] md:rounded-[0.781vw] ps-[12vw] md:ps-[3vw] md:ms-[1.563vw] shadow-sm"
|
class="thin w-[100%] md:w-[45vw] h-[10.769vw] md:h-[3.333vw] text-[2.836vw] md:text-[0.741vw] text-[#878787] rounded-[2.564vw] md:rounded-[0.781vw] ps-[12vw] md:ps-[3vw] md:ms-[1.563vw] shadow-sm"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="نام آموزش ، دوره و ... را وارد کنید"
|
placeholder="نام آموزش ، دوره و ... را وارد کنید"
|
||||||
@@ -450,6 +452,7 @@ function prevPage(){
|
|||||||
if (pageNumber.value > 1) {
|
if (pageNumber.value > 1) {
|
||||||
pageNumber.value -= 1
|
pageNumber.value -= 1
|
||||||
query.value = { ...route.query, page: pageNumber };
|
query.value = { ...route.query, page: pageNumber };
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
path: "/courses",
|
path: "/courses",
|
||||||
query: query.value,
|
query: query.value,
|
||||||
@@ -482,12 +485,16 @@ function removeCategory(){
|
|||||||
}
|
}
|
||||||
if (query.value.hasOwnProperty("price")) {
|
if (query.value.hasOwnProperty("price")) {
|
||||||
delete query.value.price;
|
delete query.value.price;
|
||||||
|
}
|
||||||
|
if (query.value.hasOwnProperty("name")) {
|
||||||
|
delete query.value.name;
|
||||||
}
|
}
|
||||||
router.push({
|
router.push({
|
||||||
path: "/courses",
|
path: "/courses",
|
||||||
query: query.value,
|
query: query.value,
|
||||||
});
|
});
|
||||||
pageNumber.value = 1
|
pageNumber.value = 1
|
||||||
|
search.value = null
|
||||||
refresh()
|
refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,6 +506,7 @@ const categories = categoryLis.data.value;
|
|||||||
|
|
||||||
function selectCategory(id) {
|
function selectCategory(id) {
|
||||||
query.value = { ...route.query, category: id };
|
query.value = { ...route.query, category: id };
|
||||||
|
|
||||||
if (query.value.hasOwnProperty("page")) {
|
if (query.value.hasOwnProperty("page")) {
|
||||||
delete query.value.page;
|
delete query.value.page;
|
||||||
}
|
}
|
||||||
@@ -514,9 +522,9 @@ function selectCategory(id) {
|
|||||||
});
|
});
|
||||||
pageNumber.value = 1
|
pageNumber.value = 1
|
||||||
refresh();
|
refresh();
|
||||||
watch(data , () => {
|
// watch(data , () => {
|
||||||
paginationLength.value = Math.ceil(data.value.count / 2);
|
// paginationLength.value = Math.ceil(data.value.count / 2);
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -565,8 +573,26 @@ const closeSortOptions = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const search = ref(null)
|
||||||
|
// watch(search, () =>{
|
||||||
|
// if (search.value.length > 2) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
const searchHandler = () =>{
|
||||||
|
query.value = { ...route.query, name: search.value };
|
||||||
|
if (query.value.hasOwnProperty("page")) {
|
||||||
|
delete query.value.page;
|
||||||
|
}
|
||||||
|
router.push({
|
||||||
|
path: "/courses",
|
||||||
|
query: query.value,
|
||||||
|
});
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
watch(data , () => {
|
||||||
|
paginationLength.value = Math.ceil(data.value.count / 2);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -269,4 +269,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <Markdown :source="source" /> -->
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// import Markdown from 'vue3-markdown-it';
|
||||||
|
// const source = 'The *quick* brown fox, jumped **over** the lazy [dog](https://en.wikipedia.org/wiki/Dog)'
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
const body = await readBody(event);
|
||||||
|
const query = getQuery(event);
|
||||||
|
console.log('c s',body);
|
||||||
|
console.log(query);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/course/${query.id}/comment`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body
|
||||||
|
});
|
||||||
|
console.log('ser com', data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -6,8 +6,9 @@ export default defineEventHandler(async (event) => {
|
|||||||
let page = query.hasOwnProperty('page') ? `page=${query.page}` : '';
|
let page = query.hasOwnProperty('page') ? `page=${query.page}` : '';
|
||||||
// let sortBy = query.hasOwnProperty('sortBy') ? `price=${query.price}` : '';
|
// let sortBy = query.hasOwnProperty('sortBy') ? `price=${query.price}` : '';
|
||||||
let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
||||||
|
let name = query.hasOwnProperty('name') ? `name=${query.name}` : '';
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/course?${category}&${page}&pageSize=2&${price}`, {
|
const data = await $fetch(`${apiBase}/course?${category}&${page}&pageSize=2&${price}&${name}`, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
@@ -17,7 +18,6 @@ export default defineEventHandler(async (event) => {
|
|||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('err :', error);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
|
||||||
|
const query = getQuery(event);
|
||||||
|
|
||||||
|
|
||||||
|
// let page = query.hasOwnProperty('page') ? `page=${query.page}` : '';
|
||||||
|
// // let sortBy = query.hasOwnProperty('sortBy') ? `price=${query.price}` : '';
|
||||||
|
// let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
||||||
|
try {
|
||||||
|
const courseHeadline = await $fetch(`${apiBase}/courseHeadline?courseId=${query.id}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'content-type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(courseHeadline);
|
||||||
|
return courseHeadline;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
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}/uploader`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
// 'Accept': 'multipart/form-data',
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
file: body.file,
|
||||||
|
directoryName: body.directoryName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log('uploader data', data);
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error.data);
|
||||||
|
// if (error.statusCode == 401) {
|
||||||
|
// setCookie(event, 'token', '', {
|
||||||
|
// httpOnly: true,
|
||||||
|
// secure: true,
|
||||||
|
// maxAge: new Date(0),
|
||||||
|
// path: '/'
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
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}/user/add`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/user/balance`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
function gregorian_to_jalali(gy, gm, gd) {
|
||||||
|
|
||||||
|
var g_d_m, jy, jm, jd, gy2, days;
|
||||||
|
g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||||
|
gy2 = gm > 2 ? gy + 1 : gy;
|
||||||
|
days =
|
||||||
|
355666 +
|
||||||
|
365 * gy +
|
||||||
|
~~((gy2 + 3) / 4) -
|
||||||
|
~~((gy2 + 99) / 100) +
|
||||||
|
~~((gy2 + 399) / 400) +
|
||||||
|
gd +
|
||||||
|
g_d_m[gm - 1];
|
||||||
|
jy = -1595 + 33 * ~~(days / 12053);
|
||||||
|
days %= 12053;
|
||||||
|
jy += 4 * ~~(days / 1461);
|
||||||
|
days %= 1461;
|
||||||
|
if (days > 365) {
|
||||||
|
jy += ~~((days - 1) / 365);
|
||||||
|
days = (days - 1) % 365;
|
||||||
|
}
|
||||||
|
if (days < 186) {
|
||||||
|
jm = 1 + ~~(days / 31);
|
||||||
|
jd = 1 + (days % 31);
|
||||||
|
} else {
|
||||||
|
jm = 7 + ~~((days - 186) / 30);
|
||||||
|
jd = 1 + ((days - 186) % 30);
|
||||||
|
}
|
||||||
|
return [jy, jm, jd];
|
||||||
|
}
|
||||||
|
|
||||||
|
export {gregorian_to_jalali}
|
||||||
Reference in New Issue
Block a user