complete progress section
This commit is contained in:
@@ -17,11 +17,11 @@
|
|||||||
<div
|
<div
|
||||||
class="w-full flex flex-col justify-center space-y-[1.042vw] md:space-y-[1.25vw]"
|
class="w-full flex flex-col justify-center space-y-[1.042vw] md:space-y-[1.25vw]"
|
||||||
>
|
>
|
||||||
<nuxt-link :to="`${props.item?.id}`"
|
<p @click="change"
|
||||||
class="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?.name }}
|
||||||
</nuxt-link>
|
</p>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex flex-col justify-between items-center py-[3vw] md:py-[0.7vw] mx-[3vw] md:mx-[0.833vw] border-t"
|
class="flex flex-col justify-between items-center py-[3vw] md:py-[0.7vw] mx-[3vw] md:mx-[0.833vw] border-t"
|
||||||
@@ -43,8 +43,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps(['item']);
|
|
||||||
|
|
||||||
|
const props = defineProps(['item']);
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
console.log(props);
|
||||||
|
const change = () =>{
|
||||||
|
router.replace(`/${props.item.id}`)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
@@ -11,19 +11,9 @@
|
|||||||
درباره ما
|
درباره ما
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
class="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]"
|
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]"
|
||||||
>
|
>
|
||||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با
|
|
||||||
استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در
|
|
||||||
ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و
|
|
||||||
کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی
|
|
||||||
در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می
|
|
||||||
طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی
|
|
||||||
الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این
|
|
||||||
صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و
|
|
||||||
شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای
|
|
||||||
اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده
|
|
||||||
قرار گیرد.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -37,7 +27,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup>
|
||||||
|
const info = await useFetch('/api/settings')
|
||||||
|
if (process.client) {
|
||||||
|
document.querySelector('.about').innerHTML = info.data.value.about
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div class="text-[#383E43] font-semibold">
|
<div class="text-[#383E43] font-semibold">
|
||||||
<p class="text-[5.11vw] md:text-[1.979vw]">{{info.data.value.title}}</p>
|
<p class="text-[5.11vw] md:text-[1.979vw]">{{info.data.value.expertise}}</p>
|
||||||
<p class="text-[3.59vw] md:text-[1.502vw]">ویدئوی آموزشی</p>
|
<p class="text-[3.59vw] md:text-[1.502vw]">ویدئوی آموزشی</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<div class="text-[#383E43] font-semibold">
|
<div class="text-[#383E43] font-semibold">
|
||||||
<p class="text-[5.11vw] md:text-[1.979vw]">4.6</p>
|
<p class="text-[5.11vw] md:text-[1.979vw]">{{info.data.value.rate}}</p>
|
||||||
<p class="text-[3.59vw] md:text-[1.502vw]">امتیاز دانشجویان به ما</p>
|
<p class="text-[3.59vw] md:text-[1.502vw]">امتیاز دانشجویان به ما</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,23 +3,21 @@
|
|||||||
<img src="/public/images/HeaderBg.jpg" class="absolute top-0 left-0 w-full h-full object-cover -z-[1] scale-x-[-1] md:scale-x-[1]" alt="">
|
<img src="/public/images/HeaderBg.jpg" class="absolute top-0 left-0 w-full h-full object-cover -z-[1] scale-x-[-1] md:scale-x-[1]" alt="">
|
||||||
<div class=" flex w-[81.04%] text-white">
|
<div class=" flex w-[81.04%] text-white">
|
||||||
<div class="flex flex-col text-start">
|
<div class="flex flex-col text-start">
|
||||||
<h2 class="text-[5.751vw] md:text-[2.188vw] font-bold mt-[25vw] md:mt-[0.052vw]">
|
<h2 class="w-[25vw] text-[5.751vw] md:text-[2.188vw] font-bold mt-[25vw] md:mt-[0.052vw]">
|
||||||
داستان برنامهنویس <br />
|
{{ headers.data?.value.header }}
|
||||||
شدنت از اینجا شروع میشه!
|
|
||||||
</h2>
|
</h2>
|
||||||
<p class="hidden md:block mt-[1.25vw] text-[1.055vw] leading-[30.38px] mb-[2.917vw]">
|
<p class="hidden md:block mt-[1.25vw] text-[1.055vw] leading-[30.38px] mb-[2.917vw]">
|
||||||
شینان، آکادمی آموزش آنلاین تخصصی برنامه نویسی، با افتخار بهترین و به روزترین مقالات و فیلم های
|
{{ headers.data?.value.titleText }}
|
||||||
آموزشی
|
|
||||||
پروژه محور و کاربردی در زمینه برنامه نویسی وب را در اختیار علاقه مندان این <br /> قرار خواهد
|
|
||||||
داد تا
|
|
||||||
بتوانند از این طریق درآمد بیشتری کسب کنند با ما همراه باشید تا گام های تبدیل شدن به توسعه دهنده وب
|
|
||||||
را از
|
|
||||||
مبتدی تا پیشرفته طی کنیم
|
|
||||||
</p>
|
</p>
|
||||||
<button
|
<nuxt-link to="/courses"
|
||||||
class="greenButton h-[8.974vw] md:h-[3.125vw] px-0 flexBox rounded-[2.051vw] md:rounded-[0.521vw] w-[26.41vw] md:w-[14.01vw] text-[3.19vw] md:text-[1.055vw] mt-[10vw] md:mt-0">شروع
|
class="greenButton h-[8.974vw] md:h-[3.125vw] px-0 flexBox rounded-[2.051vw] md:rounded-[0.521vw] w-[26.41vw] md:w-[14.01vw] text-[3.19vw] md:text-[1.055vw] mt-[10vw] md:mt-0">شروع
|
||||||
یادگیری</button>
|
یادگیری </nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
|
||||||
|
const headers = await useFetch("/api/settings")
|
||||||
|
</script>
|
||||||
@@ -22,13 +22,15 @@
|
|||||||
fill="#0D3F40"
|
fill="#0D3F40"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span
|
<h1
|
||||||
class="text-[4.544vw] md:text-[1.69vw] text-[#383E43] font-bold -tracking-[0.05vw]"
|
class="text-[4.544vw] md:text-[1.69vw] text-[#383E43] font-bold -tracking-[0.05vw]"
|
||||||
>آموزش HTML رایگان مقدماتی تا پیشرفته</span
|
|
||||||
>
|
>
|
||||||
|
{{ activeHead?.headline }}
|
||||||
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<video
|
<video
|
||||||
|
@ended="handleVideoEnded"
|
||||||
id="myVideo"
|
id="myVideo"
|
||||||
ref="video"
|
ref="video"
|
||||||
controls
|
controls
|
||||||
@@ -39,7 +41,21 @@
|
|||||||
<div
|
<div
|
||||||
class="relative flex items-center text-[4.038vw] md:text-[1.502vw] mt-[6vw] md:mt-[1.6vw] font-semibold"
|
class="relative flex items-center text-[4.038vw] md:text-[1.502vw] mt-[6vw] md:mt-[1.6vw] font-semibold"
|
||||||
>
|
>
|
||||||
{{ activeHead?.headline }}
|
<div class="w-full flex justify-between">
|
||||||
|
<h1>{{ activeHead?.description }}</h1>
|
||||||
|
<p
|
||||||
|
@click="nextHandler(item)"
|
||||||
|
class="hidden animate-bounce next text-[0.75vw] cursor-pointer flex items-center gap-[0.3vw] pe-[1vw]"
|
||||||
|
>
|
||||||
|
مشاهده قسمت بعد
|
||||||
|
<img
|
||||||
|
src="/public/images/next-svgrepo-com.svg"
|
||||||
|
alt=""
|
||||||
|
class="h-[0.8vw] rotate-180"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="absolute gap-[2vw] flex md:hidden left-0">
|
<div class="absolute gap-[2vw] flex md:hidden left-0">
|
||||||
<svg
|
<svg
|
||||||
class="h-[5.641vw] w-[5.641vw]"
|
class="h-[5.641vw] w-[5.641vw]"
|
||||||
@@ -257,6 +273,7 @@
|
|||||||
</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]"
|
||||||
>
|
>
|
||||||
@@ -340,7 +357,7 @@
|
|||||||
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
<p class="text-[2.836vw] md:text-[0.741vw] text-[#878787]">
|
||||||
پرسش جدید
|
پرسش جدید
|
||||||
</p>
|
</p>
|
||||||
{{replyId}}
|
{{ replyId }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -355,7 +372,7 @@
|
|||||||
class="flex justify-end gap-[1vw] text-[3.19vw] md:text-[0.833vw] text-white"
|
class="flex justify-end gap-[1vw] text-[3.19vw] md:text-[0.833vw] text-white"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@click="replyId = null"
|
@click="replyId = null"
|
||||||
class="h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-[#5A6268]"
|
class="h-[8.974vw] md:h-[2.292vw] w-[20.769vw] md:w-[5.573vw] rounded-[2.051vw] md:rounded-[0.521vw] bg-[#5A6268]"
|
||||||
>
|
>
|
||||||
حذف
|
حذف
|
||||||
@@ -380,7 +397,6 @@
|
|||||||
<label
|
<label
|
||||||
v-for="item in data"
|
v-for="item in data"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
|
|
||||||
class="cursor-pointer text-[#383E43] h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
class="cursor-pointer text-[#383E43] h-[14.615vw] md:h-[3.125vw] px-[3vw] md:px-[1.25vw] text-[3.59vw] md:text-[0.833vw] w-full flex justify-between"
|
||||||
>
|
>
|
||||||
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
<div class="flexBox gap-[1vw] md:gap-[0.3vw]">
|
||||||
@@ -431,7 +447,27 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<product-page-attended-coursesProgress-bar />
|
<!-- <product-page-attended-coursesProgress-bar /> -->
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="mt-[5vw] rounded-[3.846vw] md:rounded-[0.781vw] bg-[#F8F8F8] pinkShadow p-[4vw] md:p-[1vw] space-y-[6vw] md:space-y-[2vw] md:mt-[1vw] text-[#383E43]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex justify-between text-[3.19vw] md:text-[0.833vw] font-semibold text-[#383E43]"
|
||||||
|
>
|
||||||
|
<span class="text-[3.59vw] md:text-[0.938vw]">پیشرفت شما</span>
|
||||||
|
<span>{{ progress.completionPercentage }}%</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="progressbar"
|
||||||
|
class="test mt-[3vw] md:mt-[0.7vw] h-[2.051vw] md:h-[0.521vw] rounded-[2vw] md:rounded-[0.521vw]"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
:style="{ width: activeClass + '%' }"
|
||||||
|
class="bg-[#0d3f40] float-end prog rounded-[2vw] md:rounded-[0.521vw] h-[2.051vw] md:h-[0.521vw]"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -447,15 +483,42 @@ const url = ref(null);
|
|||||||
const query = ref({});
|
const query = ref({});
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const comment = ref(null);
|
const comment = ref(null);
|
||||||
|
const index = ref(0);
|
||||||
query.value = route.query;
|
query.value = route.query;
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
|
|
||||||
|
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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
async function addToProgress() {
|
||||||
|
await $fetch("/api/progressCounter", {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
id: route.query.episode,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
import progressAlert from "@/components/progressAlert.vue";
|
||||||
|
const handleVideoEnded = async () => {
|
||||||
|
|
||||||
|
addToProgress();
|
||||||
|
|
||||||
|
reload();
|
||||||
|
if (process.client) {
|
||||||
|
document.querySelector(".next").classList.remove("hidden");
|
||||||
|
}
|
||||||
|
toast.success('ویدیو به پایان رسید');
|
||||||
|
};
|
||||||
|
|
||||||
const sendComment = async () => {
|
const sendComment = async () => {
|
||||||
if (comment.value === "" || comment.value === null) {
|
if (comment.value === "" || comment.value === null) {
|
||||||
@@ -472,25 +535,23 @@ const sendComment = async () => {
|
|||||||
refresh();
|
refresh();
|
||||||
toast.success("نظر شما با موفقیت ثبت شد");
|
toast.success("نظر شما با موفقیت ثبت شد");
|
||||||
comment.value = "";
|
comment.value = "";
|
||||||
}else{
|
} else {
|
||||||
await $fetch("/api/comments/courseHeadlineReply", {
|
await $fetch("/api/comments/courseHeadlineReply", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
id: replyId,
|
id: replyId,
|
||||||
text: comment.value,
|
text: comment.value,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
refresh();
|
refresh();
|
||||||
toast.success("نظر شما با موفقیت ثبت شد");
|
toast.success("نظر شما با موفقیت ثبت شد");
|
||||||
comment.value = "";
|
comment.value = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const replyId = ref(null);
|
||||||
const replyId = ref(null)
|
|
||||||
const reply = async (id) => {
|
const reply = async (id) => {
|
||||||
replyId.value = id
|
replyId.value = id;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function copyUrl() {
|
function copyUrl() {
|
||||||
@@ -501,28 +562,78 @@ function copyUrl() {
|
|||||||
if (query.value.hasOwnProperty("episode")) {
|
if (query.value.hasOwnProperty("episode")) {
|
||||||
const fimd = data.value.find((items) => items.id === query.value.episode);
|
const fimd = data.value.find((items) => items.id === query.value.episode);
|
||||||
activeHead.value = fimd;
|
activeHead.value = fimd;
|
||||||
url.value = fimd.videoUrl;
|
const getUrl = await useFetch("/api/checkMedia", {
|
||||||
|
query: {
|
||||||
|
fileName: fimd.videoUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log("video", getUrl.data.value.url);
|
||||||
|
url.value = getUrl.data.value.url;
|
||||||
|
index.value = data.value.indexOf(fimd);
|
||||||
refresh();
|
refresh();
|
||||||
} else {
|
} else {
|
||||||
activeHead.value = data.value[0];
|
activeHead.value = data.value[0];
|
||||||
url.value = data.value[0].videoUrl;
|
const getUrl = await useFetch("/api/checkMedia", {
|
||||||
|
query: {
|
||||||
|
fileName: data.value[0].videoUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
url.value = getUrl.data.value.url;
|
||||||
|
index.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chengeVideo = (item) => {
|
async function chengeVideo(item) {
|
||||||
|
if (process.client) {
|
||||||
|
document.querySelector(".next").classList.add("hidden");
|
||||||
|
}
|
||||||
query.value = { ...route.query, episode: item.id };
|
query.value = { ...route.query, episode: item.id };
|
||||||
activeHead.value = item;
|
activeHead.value = item;
|
||||||
url.value = item.videoUrl;
|
const getUrl = await useFetch("/api/checkMedia", {
|
||||||
|
query: {
|
||||||
|
fileName: item.videoUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
url.value = getUrl.data.value.url;
|
||||||
|
index.value = data.value.indexOf(item);
|
||||||
video.value.load();
|
video.value.load();
|
||||||
router.push({
|
router.push({
|
||||||
query: query.value,
|
query: query.value,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await refresh();
|
||||||
|
}
|
||||||
|
console.log("yek", data.value[index.value]);
|
||||||
|
async function nextHandler() {
|
||||||
|
if (process.client) {
|
||||||
|
document.querySelector(".next").classList.add("hidden");
|
||||||
|
}
|
||||||
|
query.value = { ...route.query, episode: data.value[index.value + 1].id };
|
||||||
|
index.value = index.value + 1;
|
||||||
|
console.log("index", index);
|
||||||
|
// const addToProgress = await $fetch("/api/progressCounter", {
|
||||||
|
// method: "POST",
|
||||||
|
// body: {
|
||||||
|
// id: route.query.episode,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
addToProgress()
|
||||||
|
activeHead.value = data.value[index.value];
|
||||||
|
const getUrl = await useFetch("/api/checkMedia", {
|
||||||
|
query: {
|
||||||
|
fileName: data.value[index.value].videoUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
url.value = getUrl.data.value.url;
|
||||||
|
video.value.load();
|
||||||
|
activeClass.value = progress.value.completionPercentage;
|
||||||
refresh();
|
refresh();
|
||||||
};
|
reload();
|
||||||
console.log(activeHead.value.Comment);
|
router.push({
|
||||||
|
query: query.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
video {
|
video {
|
||||||
border-radius: 0.781vw;
|
border-radius: 0.781vw;
|
||||||
@@ -532,4 +643,15 @@ video {
|
|||||||
border-radius: 3.846vw;
|
border-radius: 3.846vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#progressbar {
|
||||||
|
background-color: #e5e5e5;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#progressbar > div {
|
||||||
|
background-color: #0d3f40;
|
||||||
|
float: left I !important;
|
||||||
|
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -147,5 +147,5 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps(['props'])
|
const props = defineProps(['props'])
|
||||||
console.log('props', props);
|
|
||||||
</script>
|
</script>
|
||||||
@@ -261,7 +261,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
console.log('user', authUser.value === null);
|
|
||||||
const props = defineProps(["props"], ["access"]);
|
const props = defineProps(["props"], ["access"]);
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<button
|
||||||
|
class="action px-[0.5vw]"
|
||||||
|
@click.stop="clicked"
|
||||||
|
>جهت مشاهده قسمت بعد کلیک کنید</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
clicked() {
|
||||||
|
alert("Clicked!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
+1
-1
@@ -3,7 +3,7 @@ export default defineNuxtConfig({
|
|||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
public: {
|
public: {
|
||||||
apiBase: "https://dlearn.iran.liara.run",
|
apiBase: "https://dlearn.liara.run",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
modules: [
|
modules: [
|
||||||
|
|||||||
+7
-22
@@ -133,7 +133,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]"
|
||||||
>
|
>
|
||||||
{{ tickets.data.value.length }}
|
{{ tickets?.data.value.length }}
|
||||||
تیکت
|
تیکت
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
@@ -219,7 +219,7 @@
|
|||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="lastTickets.length > 0" class="lastTickets mt-[20vw] md:mt-[2.917vw]">
|
<div v-if="lastTickets?.length > 0" class="lastTickets mt-[20vw] md:mt-[2.917vw]">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex justify-between items-center border-b pb-[0.733vw]">
|
<div class="flex justify-between items-center border-b pb-[0.733vw]">
|
||||||
<p class="text-[4.038vw] md:text-[1.055vw] font-[500]">
|
<p class="text-[4.038vw] md:text-[1.055vw] font-[500]">
|
||||||
@@ -273,19 +273,7 @@
|
|||||||
مشاهده
|
مشاهده
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="flex justify-between items-center mt-[0.833vw] px-2">
|
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] text-[#000]">
|
|
||||||
طراحی سایت
|
|
||||||
</p>
|
|
||||||
<p class="text-[3.19vw] md:text-[0.833vw] text-[#878787]">
|
|
||||||
1402/09/12
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
class="flex justify-center items-center text-[2.518vw] md:text-[0.658vw] px-[2.564vw] md:px-[0.417vw] py-[2.051vw] md:py-[0.521vw] text-[#2ED573] bg-[#2ED5731A] rounded-[2.051vw] md:rounded-[0.521vw]"
|
|
||||||
>
|
|
||||||
پاسخ داده شده
|
|
||||||
</p>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -531,10 +519,11 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const profileImage = useState('profileImage')
|
const profileImage = useState('profileImage')
|
||||||
const tickets = await useFetch("/api/ticket");
|
const tickets = await useFetch("/api/ticket/getTickets");
|
||||||
const lastTickets = tickets.data.value.slice(-2);
|
console.log('tick',tickets.data);
|
||||||
|
const lastTickets = tickets?.data?.value.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.course.slice(-2);
|
||||||
const balance = await useFetch("/api/user/balance");
|
const balance = await useFetch("/api/user/balance");
|
||||||
const { authUser } = useAuth();
|
const { authUser } = useAuth();
|
||||||
|
|
||||||
@@ -548,12 +537,8 @@ const timeDifference = today.getTime() - pastDate.getTime();
|
|||||||
const dayDifference = timeDifference / (1000 * 3600 * 24);
|
const dayDifference = timeDifference / (1000 * 3600 * 24);
|
||||||
const roundDay = Math.ceil(dayDifference)
|
const roundDay = Math.ceil(dayDifference)
|
||||||
|
|
||||||
console.log(`تفاوت بین تاریخ امروز و تاریخ گذشته: ${roundDay} روز`);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log(today);
|
|
||||||
console.log(today - authUser.value.createdAt);
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
middleware: "auth",
|
middleware: "auth",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,13 +11,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</tab>
|
</tab>
|
||||||
<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 v-for="item in myCourses.data.value.course" :key="item.id">
|
||||||
|
<ProgressCard :item="item"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</tab>
|
</tab>
|
||||||
<tab :name=tab3>
|
<!-- <tab :name=tab3>
|
||||||
محتوا سوم
|
محتوا سوم
|
||||||
</tab>
|
</tab> -->
|
||||||
<tab :name=tab4>
|
<tab :name=tab4>
|
||||||
محتوا سوم
|
|
||||||
</tab>
|
</tab>
|
||||||
</tabs>
|
</tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ const edit = async (formData) => {
|
|||||||
};
|
};
|
||||||
//const token = getCookie(event, 'token');
|
//const token = getCookie(event, 'token');
|
||||||
async function changePhoto(val) {
|
async function changePhoto(val) {
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("directoryName", "test");
|
formData.append("directoryName", "test");
|
||||||
formData.append("file", val.target.files[0]);
|
formData.append("file", val.target.files[0]);
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ import {Tabs, Tab} from 'vue3-tabs-component';
|
|||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
const toast = useToast()
|
const toast = useToast()
|
||||||
|
|
||||||
const { data: tickets, refresh: load } = await useFetch("/api/ticket");
|
const { data: tickets, refresh: load } = await useFetch("/api/ticket/getTickets");
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const addTicketForm = ref(false);
|
const addTicketForm = ref(false);
|
||||||
const subject = ref(null);
|
const subject = ref(null);
|
||||||
@@ -413,7 +413,7 @@ const sendTicket = async () => {
|
|||||||
if (subject.value === null) {
|
if (subject.value === null) {
|
||||||
return toast.error("موضوع تیکت را وارد کنید")
|
return toast.error("موضوع تیکت را وارد کنید")
|
||||||
}
|
}
|
||||||
const data = await useFetch("/api/ticket", {
|
const data = await useFetch("/api/ticket/send", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: {
|
body: {
|
||||||
subject: subject.value,
|
subject: subject.value,
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||||
|
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="0 0 55.752 55.752" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<path d="M43.006,23.916c-0.28-0.282-0.59-0.52-0.912-0.727L20.485,1.581c-2.109-2.107-5.527-2.108-7.637,0.001
|
||||||
|
c-2.109,2.108-2.109,5.527,0,7.637l18.611,18.609L12.754,46.535c-2.11,2.107-2.11,5.527,0,7.637c1.055,1.053,2.436,1.58,3.817,1.58
|
||||||
|
s2.765-0.527,3.817-1.582l21.706-21.703c0.322-0.207,0.631-0.444,0.912-0.727c1.08-1.08,1.598-2.498,1.574-3.912
|
||||||
|
C44.605,26.413,44.086,24.993,43.006,23.916z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 744 B |
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
@@ -0,0 +1,20 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
const query = getQuery(event);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/uploader/file?fileName=${query.fileName}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
const { public: { apiBase } } = useRuntimeConfig();
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
const token = getCookie(event, 'token');
|
const token = getCookie(event, 'token');
|
||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
console.log(body);
|
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/courseHeadlineComment/create`, {
|
const data = await $fetch(`${apiBase}/courseHeadlineComment/create`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -12,7 +12,7 @@ console.log(body);
|
|||||||
},
|
},
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
console.log(data);
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
const { public: { apiBase } } = useRuntimeConfig();
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
const token = getCookie(event, 'token');
|
const token = getCookie(event, 'token');
|
||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
console.log(body);
|
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/courseHeadlineComment/reply`, {
|
const data = await $fetch(`${apiBase}/courseHeadlineComment/reply`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ export default defineEventHandler(async (event) => {
|
|||||||
},
|
},
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
console.log(data);
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
|
||||||
|
const query = getQuery(event);
|
||||||
|
let category = query.hasOwnProperty('category') ? `categoryId=${query.category}` : '';
|
||||||
|
let page = query.hasOwnProperty('page') ? `page=${query.page}` : '';
|
||||||
|
// let sortBy = query.hasOwnProperty('sortBy') ? `price=${query.price}` : '';
|
||||||
|
let price = query.hasOwnProperty('price') ? `price=${query.price}` : '';
|
||||||
|
let name = query.hasOwnProperty('name') ? `name=${query.name}` : '';
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/course?${category}&${page}&pageSize=2&${price}&${name}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'content-type': 'application/json'
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const body = await readBody(event);
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/course/${body.id}?userId=${body.userId}`, {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
|
const body = await readBody(event);
|
||||||
|
const token = getCookie(event, 'token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await $fetch(`${apiBase}/courseHeadline/complete/${body.id}`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Authorization': `Bearer ${token}`
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
|
|
||||||
const formData = await readFormData(event);
|
const formData = await readFormData(event);
|
||||||
console.log(formData);
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -19,10 +19,10 @@ export default defineEventHandler(async (event) => {
|
|||||||
'Authorization': `Bearer ${token}`
|
'Authorization': `Bearer ${token}`
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
console.log('uplodar', data);
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error.data);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export default defineEventHandler(async (event) => {
|
|||||||
const { public: { apiBase } } = useRuntimeConfig();
|
const { public: { apiBase } } = useRuntimeConfig();
|
||||||
const token = getCookie(event, 'token');
|
const token = getCookie(event, 'token');
|
||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
console.log(body);
|
|
||||||
try {
|
try {
|
||||||
const data = await $fetch(`${apiBase}/user/registerCourse`, {
|
const data = await $fetch(`${apiBase}/user/registerCourse`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -12,10 +12,10 @@ export default defineEventHandler(async (event) => {
|
|||||||
},
|
},
|
||||||
body
|
body
|
||||||
});
|
});
|
||||||
console.log(data);
|
|
||||||
return data;
|
return data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('errors',error.data);
|
|
||||||
if (error.status === 406) {
|
if (error.status === 406) {
|
||||||
return{
|
return{
|
||||||
status: 406,
|
status: 406,
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export const jTime = (d) => new Date(d).toLocaleDateString('en-US', { hour: '2-digit', minute: '2-digit' })
|
||||||
Reference in New Issue
Block a user