From a5e20c1cd624f2fe4c9d3048e938ad88d62ede73 Mon Sep 17 00:00:00 2001 From: mustafa-rezae <mustafa.rezae01@gmail.com> Date: Thu, 27 Feb 2025 13:18:59 +0330 Subject: [PATCH] Work on pages --- assets/hadith/images/robot-indicator.svg | 9 + .../hadith/library-show/AccordionMenu..vue | 178 ++++--- pages/hadith/chat-bot.vue | 472 +++++++++++++++++- pages/hadith/library/[id]/[slug]/index.vue | 12 +- 4 files changed, 551 insertions(+), 120 deletions(-) create mode 100644 assets/hadith/images/robot-indicator.svg diff --git a/assets/hadith/images/robot-indicator.svg b/assets/hadith/images/robot-indicator.svg new file mode 100644 index 0000000..1215d98 --- /dev/null +++ b/assets/hadith/images/robot-indicator.svg @@ -0,0 +1,9 @@ +<svg width="16" height="27" viewBox="0 0 16 27" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M2.79031 13.8107C5.19508 12.8313 7.08122 10.8959 8 8.47239C8.91878 10.8959 10.8049 12.8313 13.2097 13.8107L13.5599 13.9533C10.9698 14.8404 8.92567 16.8559 8 19.427C7.07433 16.8559 5.03017 14.8404 2.44014 13.9533L2.79031 13.8107Z" stroke="url(#paint0_linear_67_6564)" stroke-linejoin="round"/> +<defs> +<linearGradient id="paint0_linear_67_6564" x1="15.0921" y1="7" x2="0.0931545" y2="7.27651" gradientUnits="userSpaceOnUse"> +<stop stop-color="#D284FF"/> +<stop offset="1" stop-color="#4D00FF"/> +</linearGradient> +</defs> +</svg> diff --git a/components/hadith/library-show/AccordionMenu..vue b/components/hadith/library-show/AccordionMenu..vue index 281a6f1..6bc7e97 100644 --- a/components/hadith/library-show/AccordionMenu..vue +++ b/components/hadith/library-show/AccordionMenu..vue @@ -44,75 +44,70 @@ const items = [ }, ]; -function toggleAccordion(id) { - const allHiddenClasses = querySelectorAll(".hidden"); - console.info(element); - - allHiddenClasses.forEach((element) => { - console.info(element); - // element.classList.remove('hidden') - }); +function toggleAccordion(id, event) { const content = document.getElementById(`content-${id}`); const icon = document.getElementById(`icon-${id}`); + event.target.classList.toggle("active"); // Toggle visibility content.classList.toggle("hidden"); // Rotate icon - icon.classList.toggle("rotate-180"); + icon.classList.toggle("active"); } </script> <template> <div class="accordion-menu max-w-xl mx-auto p-4"> <!-- Parent Accordion Item 1 --> - <div class="mb-2"> + <div class="accordion-menu-item mb-2"> <button - class="w-full flex justify-between items-center p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-all delay-500 duration-300 ease-in-out" - @click.prevent="toggleAccordion('parent1')" + type="button" + class="w-full flex justify-start items-center p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-all delay-500 duration-300 ease-in-out" + @click.exact="toggleAccordion('parent1', $event)" > - <span>Parent 1</span> - <svg - id="icon-parent1" - class="w-5 h-5 transform transition-transform" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M19 9l-7 7-7-7" - /> - </svg> + <div id="icon-parent1" class="icon-container"> + <UIcon class="plus" name="i-lucide-plus"></UIcon> + <UIcon class="minus" name="i-lucide-minus"></UIcon> + </div> + <span>فصل اول</span> </button> <div id="content-parent1" - class="mt-2 pl-4 hidden transition delay-500 duration-300 ease-in-out" + class="mt-2 pe-4 hidden transition delay-500 duration-300 ease-in-out" > <!-- Child Accordion Item 1 --> <div class="mb-2 transition delay-500 duration-300 ease-in-out"> <button class="w-full flex justify-between items-center p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all" - @click.prevent="toggleAccordion('child1')" + @click.exact.prevent="toggleAccordion('child1', $event)" > + <div id="icon-child1" class="icon-container"> + <UIcon class="plus" name="i-lucide-plus"></UIcon> + <UIcon class="minus" name="i-lucide-minus"></UIcon> + </div> + <span>Child 1.1</span> - <svg - id="icon-child1" - class="w-5 h-5 transform transition-transform" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M19 9l-7 7-7-7" - /> - </svg> </button> - <div id="content-child1" class="mt-2 pl-4 hidden"> + <div id="content-child1" class="mt-2 pe-4 hidden"> + <!-- dadadad --> + <button + class="w-full flex justify-between items-center p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all" + @click.exact.prevent="toggleAccordion('child3', $event)" + > + <div id="icon-parent3" class="icon-container"> + <UIcon class="plus" name="i-lucide-plus"></UIcon> + <UIcon class="minus" name="i-lucide-minus"></UIcon> + </div> + + <span>Child 1.1</span> + </button> + <div id="content-child3" class="mt-2 pe-4 hidden"> + <p class="p-3 bg-gray-50 rounded-lg"> + This is the content of Child 1.1. + </p> + </div> + + <!-- sdsadadasd --> <p class="p-3 bg-gray-50 rounded-lg"> This is the content of Child 1.1. </p> @@ -122,25 +117,15 @@ function toggleAccordion(id) { <div class="mb-2 transition delay-500 duration-300 ease-in-out"> <button class="w-full flex justify-between items-center p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all" - @click.prevent="toggleAccordion('child2')" + @click.exact.prevent="toggleAccordion('child2', $event)" > + <div id="icon-child2" class="icon-container"> + <UIcon class="plus" name="i-lucide-plus"></UIcon> + <UIcon class="minus" name="i-lucide-minus"></UIcon> + </div> <span>Child 1.2</span> - <svg - id="icon-child2" - class="w-5 h-5 transform transition-transform" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M19 9l-7 7-7-7" - /> - </svg> </button> - <div id="content-child2" class="mt-2 pl-4 hidden"> + <div id="content-child2" class="mt-2 pe-4 hidden"> <p class="p-3 bg-gray-50 rounded-lg"> This is the content of Child 1.2. </p> @@ -148,36 +133,49 @@ function toggleAccordion(id) { </div> </div> </div> - - <!-- Parent Accordion Item 2 --> - <div class="mb-2"> - <button - class="w-full flex justify-between items-center p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-all" - @click.prevent="toggleAccordion('parent2')" - > - <span>Parent 2</span> - <svg - id="icon-parent2" - class="w-5 h-5 transform transition-transform" - fill="none" - stroke="currentColor" - viewBox="0 0 24 24" - > - <path - stroke-linecap="round" - stroke-linejoin="round" - stroke-width="2" - d="M19 9l-7 7-7-7" - /> - </svg> - </button> - <div id="content-parent2" class="mt-2 pl-4 hidden"> - <p class="p-3 bg-gray-50 rounded-lg"> - This is the content of Parent 2. - </p> - </div> - </div> </div> </template> -<style scoped></style> +<style scoped> +.accordion-menu { + .accordion-menu-item { + font-family: IRANSansX; + font-weight: 400; + font-size: 13px; + line-height: 19.5px; + letter-spacing: 0%; + text-align: right; + color: var(--ui-color-two); + + .icon-container { + .minus { + display: none; + } + .plus { + display: inline-block; + } + } + + .icon-container { + &.active { + .plus { + display: none; + } + .minus { + display: inline-block; + } + } + } + + button.active { + border: 0.3px solid #29d985; + background: linear-gradient(320.71deg, #b9fde0 6.56%, #e4f9f0 69.69%); + + button { + background: #f7fffd; + border: 0.3px solid #29d985; + } + } + } +} +</style> diff --git a/pages/hadith/chat-bot.vue b/pages/hadith/chat-bot.vue index ab9512c..f6276bc 100644 --- a/pages/hadith/chat-bot.vue +++ b/pages/hadith/chat-bot.vue @@ -1,30 +1,448 @@ -<template> - <HadithLayout> </HadithLayout> -</template> -<script> -export default { +<script setup> +definePageMeta({ + layout: false, name: "hadithChatBot", - setup() { - useHead({ - title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | چت بات `, - meta: [ - { name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" }, - ], - bodyAttrs: { - class: import.meta.env.VITE_HADITH_SYSTEM, - }, - }); +}); +useHead({ + name: "hadithChatBot", + title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | جستجو`, + meta: [ + { name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" }, + ], + bodyAttrs: { + class: import.meta.env.VITE_HADITH_SYSTEM, + }, +}); - definePageMeta({ - layout: false, - name: "hadithChatBot", - }); - }, - components: { - // SectionOne: defineAsyncComponent(() => - // import("@hadith/components/hadith/hero-page/SectionOne.vue") - // ), - }, -}; +const state = reactive({ + filters: [ + { + label: "خلاصه سازی", + icon: "i-lucide-bookmark", + + children: [ + { + label: "خلاصهسازی حدیث", + }, + { + label: "خلاصهسازی بابهای مختلف کتاب الکافی", + }, + { + label: "خلاصهسازی احادیث درباره اخلاق و رفتار", + }, + { + label: "خلاصهسازی احادیث با موضوع نماز و عبادات", + }, + { + label: "خلاصهسازی احادیث از امام علی (ع)", + }, + ], + }, + { + label: "دسته بندی", + icon: "i-lucide-bookmark", + children: [ + { + label: "خلاصهسازی حدیث", + }, + { + label: "خلاصهسازی بابهای مختلف کتاب الکافی", + }, + { + label: "خلاصهسازی احادیث درباره اخلاق و رفتار", + }, + { + label: "خلاصهسازی احادیث با موضوع نماز و عبادات", + }, + { + label: "خلاصهسازی احادیث از امام علی (ع)", + }, + ], + }, + { + label: "کلمات کلیدی", + icon: "i-lucide-bookmark", + children: [ + { + label: "خلاصهسازی حدیث", + }, + { + label: "خلاصهسازی بابهای مختلف کتاب الکافی", + }, + { + label: "خلاصهسازی احادیث درباره اخلاق و رفتار", + }, + { + label: "خلاصهسازی احادیث با موضوع نماز و عبادات", + }, + { + label: "خلاصهسازی احادیث از امام علی (ع)", + }, + ], + }, + { + label: "تشخیص موجودی", + icon: "i-lucide-bookmark", + children: [ + { + label: "خلاصهسازی حدیث", + }, + { + label: "خلاصهسازی بابهای مختلف کتاب الکافی", + }, + { + label: "خلاصهسازی احادیث درباره اخلاق و رفتار", + }, + { + label: "خلاصهسازی احادیث با موضوع نماز و عبادات", + }, + { + label: "خلاصهسازی احادیث از امام علی (ع)", + }, + ], + }, + ], + list: new Array(3).fill(0), + value: "", +}); + +// components declaration +const HadithLayout = defineAsyncComponent(() => + import("@hadith/layouts/HadithLayout.vue") +); +const NavigationMenu = defineAsyncComponent(() => + import("@hadith/components/hadith/NavigationMenu.vue") +); </script> -<style scoped></style> + +<template> + <HadithLayout> + <div class="chat-bot-page h-full"> + <div class="page-container pt-20 h-full"> + <navigation-menu></navigation-menu> + + <UContainer + ui="{ + base: 'sm:px-6 lg:px-4', + }" + class="page-inner-container sm:px-6 lg:px-4 h-full" + > + <div class="page-content flex flex-col py-12 p-2 h-full"> + <div v-if="state.list.length" class="messages basis-full"> + <div class="r-message flex items-center mb-6"> + <UIcon + size="18" + name="i-lucide-sparkle" + class="star-icon align-self-start mt-1" + ></UIcon> + <p class="basis-full message"> + من می تونم متن حدیث را خلاصه کنم. لطفا محتوای خود را بفرستید + </p> + <UButton + class="p-0 copy-icon align-self-end" + icon="i-lucide-clipboard-copy" + variant="" + > + </UButton> + </div> + <div class="u-message flex justify-end mb-6"> + <div class="u-message-container"> + <p class="message"> + عَنِ الْحَسَنِ بْنِ عَلِيِّ بْنِ يُوسُفَ، عَنْ جَدِّهِ، + قَالَ: قَالَ أَبُو عَبْدِ اللَّهِ (عَلَيْهِ السَّلَامُ): + إِنَّمَا يَدْرُسُ الْإِنسَانُ لِيَعْلَمَ، وَإِنَّمَا + يَعْلَمُ لِيَعْمَلَ، وَإِنَّمَا يَعْمَلُ لِيُعْرَفَ بِهِ، + وَإِنَّمَا يُعْرَفُ بِهِ لِيُقْبَلَ بِهِ، وَإِنَّمَا + يُقْبَلُ بِهِ لِيُؤْمَنَ عَلَيْهِ، وَإِنَّمَا يُؤْمَنُ + عَلَيْهِ لِيُدْخَلَ الْجَنَّةَ + </p> + <p>این حدیث را لطفا خلاصه کن</p> + </div> + </div> + + <div class="r-message flex items-center mb-6"> + <UIcon + size="18" + name="i-lucide-sparkle" + class="star-icon align-self-start mt-1" + ></UIcon> + <p class="basis-full message"> + خلاصه این حدیث چنین است: امام صادق (علیهالسلام) میفرمایند: + انسان دانش میآموزد تا به آن عمل کند، و با عملش شناخته شود. + شناخت، سبب پذیرش او میشود، پذیرش باعث امانیافتن او میشود، و + این امان یافتن، در نهایت او را به بهشت میرساند. + </p> + <UButton + class="p-0 copy-icon align-self-end" + icon="i-lucide-clipboard-copy" + variant="" + > + </UButton> + </div> + </div> + + <div class="px-6 my-auto"> + <div class="flex editor"> + <UTextarea + class="basis-full" + size="xl" + placeholder="به نظرم باید یکی دیگه بنویسی" + variant="ghost" + v-model="value" + :rows="state.list.length ? 1 : 3" + :maxrows="2" + autoresize + @update:modelValue="onUpdateValue" + @change="onChangeValue" + @blur="onBlur" + /> + <UButton + class="p-0 send align-self-start" + icon="i-lucide-arrow-up" + variant="solid" + > + </UButton> + </div> + <div class="filters mt-3" v-if="state.list.length == 0"> + <template v-for="(item, index) in state.filters"> + <UDropdownMenu + v-if="item.children?.length" + :items="item.children" + :ui="{ + arrow: 'arrow', + group: 'group', + label: 'label', + separator: 'separator', + item: 'item', + itemLeadingIcon: 'itemLeadingIcon', + itemLeadingAvatar: 'itemLeadingAvatar', + itemLeadingAvatarSize: 'itemLeadingAvatarSize', + itemTrailing: 'itemTrailing', + itemLabelExternalIcon: 'itemLabelExternalIcon', + content: 'filters-content w-82', + }" + class="filter-dropdown me-2" + > + <UButton + :label="item.label" + icon="i-lucide-menu" + color="neutral" + variant="outline" + /> + </UDropdownMenu> + + <UButton + v-else + :icon="item.icon" + :label="item.label" + class="w-full flex justify-center items-center me-3" + > + </UButton> + </template> + </div> + </div> + </div> + </UContainer> + </div> + </div> + </HadithLayout> +</template> + +<style scoped> +.chat-bot-page { + background: linear-gradient(137.41deg, #ffffff -42.82%, #e5e0ff 87.9%); + .page-container { + .page-inner-container { + .r-message { + .star-icon { + color: #4d00ff; + + border: 1px solid; + + border-image-source: linear-gradient( + 268.94deg, + #d284ff -0.65%, + #4d00ff 104.59% + ); + } + .message { + font-family: IRANSansX; + font-weight: 400; + font-size: 14px; + line-height: 27px; + letter-spacing: 0%; + text-align: right; + color: var(--ui-color-two); + margin-inline-end: 1em; + margin-inline-start: 0.5em; + } + + .copy-icon { + color: #545aea; + width: 20; + height: 20; + } + } + .u-message { + .u-message-container { + width: 280; + height: 240; + max-width: 280px; + background: linear-gradient( + 169.5deg, + #ffffff 25.51%, + #e5e0ff 158.51% + ); + + gap: 10px; + border-radius: 12px; + border-width: 0.3px; + padding: 1em; + + border: 0.3px solid #d9d9d9; + box-shadow: 0px 1px 4px 0px #0000000d; + + font-family: IRANSansX; + font-weight: 400; + font-size: 13px; + line-height: 26px; + letter-spacing: 0%; + text-align: right; + + color: var(--ui-color-two); + } + } + + .editor { + width: 672; + height: 64; + + border-radius: 12px; + border-width: 0.5px; + padding-top: 12px; + padding-right: 24px; + padding-bottom: 12px; + padding-left: 12px; + + background: linear-gradient(0deg, #ffffff 32.03%, #e5e0ff 135.16%); + border: 0.5px solid; + + border-image-source: linear-gradient( + 268.94deg, + #d284ff -0.65%, + #4d00ff 104.59% + ); + box-shadow: 0px 1px 4px 0px #0000000d; + + font-family: IRANSansX; + font-weight: 300; + font-size: 14px; + line-height: 21px; + letter-spacing: 0%; + text-align: right; + color: #8a92a8; + .send { + width: 3em; /*40px;*/ + height: 2.8em; /*40px;*/ + gap: 1px; + border-radius: 24px; + background: #1b2132; + color: #fff; + display: flex; + justify-content: center; + align-items: center; + } + } + .filters { + .filter-dropdown { + width: 122.5999984741211; + height: 32; + gap: 4px; + + border-radius: 8px; + border-width: 1px; + border-style: solid; + border-color: #4d00ff; + /* border-image: linear-gradient(268.94deg, #d284ff, #4d00ff) 1; */ + + padding: 8px; + box-shadow: 0px 1px 4px 0px #0000000d; + + font-family: IRANSansX; + font-weight: 400; + font-size: 11px; + line-height: 16.5px; + letter-spacing: 0%; + text-align: center; + + color: var(--ui-color-two); + } + .filters-content { + width: 328; + height: 234; + gap: 12px; + border-radius: 12px; + border-width: 0.3px; + padding: 8px; + background: #ffffff; + border: 0.3px solid #4d00ff; + + border-image-source: linear-gradient( + 268.94deg, + #d284ff -0.65%, + #4d00ff 104.59% + ); + box-shadow: 0px 1px 4px 0px #0000000d; + } + } + } + } +} +</style> + +<style> +.chat-bot-page { + .page-container { + .page-inner-container { + .editor { + textarea { + resize: none; + background: transparent; + color: #8a92a8; + } + } + } + } +} +.filters-content { + width: 328; + height: 234; + gap: 12px; + border-radius: 12px; + border-width: 1px; + padding: 8px; + background: #ffffff; + border: 0.3px solid #4d00ff; + + /* border-image-source: linear-gradient( + 268.94deg, + #d284ff -0.65%, + #4d00ff 104.59% + ); */ + box-shadow: 0px 1px 4px 0px #0000000d; + .item { + margin-bottom: 0.5em; + width: 312; + height: 34; + gap: 10px; + border-radius: 8px; + padding-top: 8px; + padding-right: 12px; + padding-bottom: 8px; + padding-left: 12px; + &:hover { + background: linear-gradient(137.41deg, #ffffff -42.82%, #e5e0ff 87.9%); + } + } +} +</style> diff --git a/pages/hadith/library/[id]/[slug]/index.vue b/pages/hadith/library/[id]/[slug]/index.vue index be63c2a..f1b619c 100644 --- a/pages/hadith/library/[id]/[slug]/index.vue +++ b/pages/hadith/library/[id]/[slug]/index.vue @@ -136,13 +136,13 @@ const AccordionMenu = defineAsyncComponent(() => :ui="{ footer: 'modal-footer', overlay: 'modal-overlay', - content: 'modal-content', + content: 'modal-content accordion-menu', header: 'modal-header', wrapper: 'modal-wrapper', body: 'modal-body', title: 'modal-title', description: 'modal-description', - close: 'modal-close', + close: 'modal-close ring-[white]', }" title="فهرست" :close="{ @@ -151,7 +151,6 @@ const AccordionMenu = defineAsyncComponent(() => class: 'rounded-full', }" > - <UButton label="Open" color="neutral" variant="subtle" /> <!-- <template #header></template> --> <!-- <template #content></template> --> <template #body> @@ -232,3 +231,10 @@ const AccordionMenu = defineAsyncComponent(() => } } </style> + +<style> +.accordion-menu { + .modal-close { + } +} +</style>