Update and debug

This commit is contained in:
mustafa-rezae 2025-03-11 13:46:19 +03:30
parent 1cae9689c5
commit 0f155d2f04
23 changed files with 1138 additions and 651 deletions

3
.gitmodules vendored
View File

@ -7,3 +7,6 @@
[submodule "systems/hadith_ui"]
path = systems/hadith_ui
url = https://git2.tavasi.ir/front/hadith_ui.git
[submodule "systems/chat_ui"]
path = systems/chat_ui
url = https://git2.tavasi.ir/front/chat_ui.git

25
GIT_SUBMODULE.md Normal file
View File

@ -0,0 +1,25 @@
Add new repo:
git submodule add https://git2.tavasi.ir/front/chat_ui.git systems/chat_ui -f
Cloning a Repository with Submodules
If you clone a repository that contains submodules, you'll need to initialize and update the submodules:
git clone <repository-url>
cd <repository-directory>
git submodule init
git submodule update
Or, you can do it in one step:
git clone --recurse-submodules <repository-url>
Updating Submodules
To update a submodule to the latest commit on its branch:
git submodule update --remote
Removing a Submodule
Removing a submodule is a bit more involved:
Remove the submodule entry from .gitmodules.
Stage the .gitmodules changes: git add .gitmodules.
Remove the submodule from the working tree and index: git rm --cached <path-to-submodule>.
Delete the submodule directory: rm -rf <path-to-submodule>.
Commit the changes: git commit -m "Removed submodule <submodule-name>".

50
app.vue
View File

@ -29,31 +29,39 @@
<script setup lang="ts">
import { fa_ir } from "@nuxt/ui/locale";
onMounted(() => {
// const toast = useToast();
// toast.add({
// title: "hello world",
// });
});
// import { useCounterStore } from "~/stores/counter";
// import { storeToRefs } from "pinia";
// export default {
// setup() {
// definePageMeta({
// colorMode: "light",
// });
// },
// mounted() {
// access the `store` variable anywhere in the component
// const store = useCounterStore();
// const { count, doubleCount } = storeToRefs(store);
// const { increment } = store;
// console.info(this.$config.public.TAHRIR_ASSETS_URL);
// console.info(this.$config.public.PUBLIC_JAHAT_ASSETS_URL);
// console.info(this.$config.public.VITE_APP_NAME);
// console.info(import.meta.env.VITE_APP_NAME);
// console.info(this.$config.public);
// console.info(this.$config.public.TITLE);
// console.info(this.$config.public.NODE_ENV);
// console.info(this.$config.public.VITE_APP_NAME);
// console.info(this.$config.public.VITE_BASE_URL);
// console.info(this.$config.public.VITE_BASE_URL);
// },
// setup() {
// definePageMeta({
// colorMode: "light",
// });
// },
// mounted() {
// access the `store` variable anywhere in the component
// const store = useCounterStore();
// const { count, doubleCount } = storeToRefs(store);
// const { increment } = store;
// console.info(this.$config.public.TAHRIR_ASSETS_URL);
// console.info(this.$config.public.PUBLIC_JAHAT_ASSETS_URL);
// console.info(this.$config.public.VITE_APP_NAME);
// console.info(import.meta.env.VITE_APP_NAME);
// console.info(this.$config.public);
// console.info(this.$config.public.TITLE);
// console.info(this.$config.public.NODE_ENV);
// console.info(this.$config.public.VITE_APP_NAME);
// console.info(this.$config.public.VITE_BASE_URL);
// console.info(this.$config.public.VITE_BASE_URL);
// },
// methods: {
// logSomeError(error) {
// console.info("logSomeError", error);

View File

@ -60,3 +60,6 @@
// responsive
@import "responsive/responsive";
// @import "tailwindcss";
// @import "@nuxt/ui";

View File

@ -59,3 +59,6 @@
// responsive
@import "responsive/responsive";
// @import "tailwindcss";
// @import "@nuxt/ui";

View File

@ -1,4 +1,5 @@
<template>
<client-only>
<aside
class="nav-sidebar"
:class="[
@ -68,7 +69,10 @@
</span>
</NuxtLink>
<ul class="sidebar-sub-level-items li-child" :id="item.link">
<ul
class="sidebar-sub-level-items li-child"
:id="item.link"
>
<li class="fly-out-top-item active gl-link">
<span class="fly-out-top-item-container">
<strong class="fly-out-top-item-name">
@ -207,8 +211,14 @@
@mouseleave="emitCustomEvent($event, 'out')"
>
<a class="has-sub-items gl-link">
<svg v-if="isGuest && showRegister" class="icon icon-personal">
<use class="icon-personal" xlink:href="#icon-personal"></use>
<svg
v-if="isGuest && showRegister"
class="icon icon-personal"
>
<use
class="icon-personal"
xlink:href="#icon-personal"
></use>
</svg>
<img
v-else
@ -338,6 +348,7 @@
<SvgIconComponent></SvgIconComponent>
</aside>
</client-only>
</template>
<script>
import { mapState, mapActions } from "pinia";

View File

@ -0,0 +1,80 @@
<template>
<div>
<input type="file" accept="image/*" @change="onFileChange" />
<div v-if="imageSrc" class="cropper-container">
<img ref="image" :src="imageSrc" alt="Image to crop" />
</div>
<button v-if="imageSrc" @click="cropImage">Crop and Upload</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
const imageSrc = ref(null);
const image = ref(null);
let cropper = null;
const onFileChange = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (event) => {
imageSrc.value = event.target.result;
initCropper();
};
reader.readAsDataURL(file);
}
};
const initCropper = () => {
if (cropper) {
cropper.destroy();
}
cropper = new Cropper(image.value, {
aspectRatio: 1, // Set aspect ratio (e.g., 1 for square)
viewMode: 1, // Restrict the crop box to the size of the image
});
};
const cropImage = () => {
if (cropper) {
const croppedCanvas = cropper.getCroppedCanvas();
croppedCanvas.toBlob((blob) => {
uploadImage(blob);
});
}
};
const uploadImage = async (blob) => {
const formData = new FormData();
formData.append('image', blob, 'cropped-image.png');
try {
const response = await $fetch('/api/upload', {
method: 'POST',
body: formData,
});
alert('Image uploaded successfully!');
console.log('Upload response:', response);
} catch (error) {
console.error('Error uploading image:', error);
alert('Error uploading image');
}
};
onBeforeUnmount(() => {
if (cropper) {
cropper.destroy();
}
});
</script>
<style scoped>
.cropper-container {
max-width: 100%;
margin-top: 20px;
}
</style>

View File

@ -1,44 +1,44 @@
import { useStorage } from "@vueuse/core";
// import { useStorage } from "@vueuse/core";
import { ref } from "vue";
import { useCommonStore } from "~/stores/commonStore";
// import { ref } from "vue";
// import { useCommonStore } from "~/stores/commonStore";
export function useMyComposable() {
const count = ref(0);
// export function useMyComposable() {
// const count = ref(0);
const increment = () => {
count.value++;
};
// const increment = () => {
// count.value++;
// };
const decrement = () => {
count.value--;
};
// const decrement = () => {
// count.value--;
// };
return {
count,
increment,
decrement,
};
}
// return {
// count,
// increment,
// decrement,
// };
// }
export function useGetSchema() {
const commonStore = useCommonStore();
// export function useGetSchema() {
// const commonStore = useCommonStore();
try {
return useAsyncData("shema", () =>
$fetch("/api/ali", {
headers: {
headers: { Authorization: useStorage("id_token") },
},
method: "post",
body: {
organ: commonStore.organNameGetter,
system: "search",
build_state: buildState(),
},
})
);
} catch (err) {
console.info(err);
}
}
// try {
// return useAsyncData("shema", () =>
// $fetch("/api/ali", {
// headers: {
// headers: { Authorization: useStorage("id_token") },
// },
// method: "post",
// body: {
// organ: commonStore.organNameGetter,
// system: "search",
// build_state: buildState(),
// },
// })
// );
// } catch (err) {
// console.info(err);
// }
// }

View File

@ -1,17 +0,0 @@
<script setup>
import { clearBodyClass } from "@manuals/utilities";
onMounted(() => {
clearBodyClass();
});
onUnmounted(() => {
clearBodyClass();
});
</script>
<template>
<main class="h-full">
<slot name="named-slot"></slot>
<slot></slot>
</main>
</template>

View File

@ -1,8 +1,9 @@
<!-- layouts/default.vue -->
<template>
<div>
<header v-if="buildName() != 'majles'">
<!-- //////////////////// begin navbar //////////////////// -->
<template v-if="$attrs.showNavbar">
<header v-if="buildName() != 'majles'">
<nav
class="navbar navbar-expand-md navbar-light bg-light"
:class="{ expanded: !isSidebarCollapsed }"
@ -145,8 +146,10 @@
</ul>
</div>
</nav>
<!-- //////////////////// end navbar //////////////////// -->
</header>
</template>
<!-- //////////////////// end navbar //////////////////// -->
<!-- <the-sidebar :showUserAvatar="true" :menu="menu"></the-sidebar> -->
<the-sidebar
:showUserAvatar="true"
@ -154,7 +157,11 @@
@statusPag="statusPag"
></the-sidebar>
<main class="main-page__content" :class="{ expanded: !isSidebarCollapsed }">
<client-only>
<main
class="main-page__content"
:class="{ expanded: !isSidebarCollapsed }"
>
<!-- <div class="pages list-page"> -->
<!-- <div class="pages-content align-items-stretch p-0"> -->
<!-- <div class="flex-grow-1"> -->
@ -164,6 +171,7 @@
<!-- </div> -->
<!-- </div> -->
</main>
</client-only>
</div>
</template>

View File

@ -33,6 +33,8 @@ export default {
]),
// callFrom : page | modal
async authBase(methodName, callFrom = "page") {
const toast = useToast();
// this.$v.$touch();
const route = useRoute();
const router = useRouter();
@ -51,16 +53,19 @@ export default {
this[methodName]()
.then((res) => {
// mySwalToast({
// title: res.message,
// icon: "success",
// timer: 2000,
// });
toast.add({
title: res.message,
icon: "success",
timer: 2000,
});
if (callFrom == "modal") {
// fired event cached in the Group.vue and ChatList.vue
const { $eventBus } = useNuxtApp();
$eventBus.emit("authenticated-by-modal", route.query["invite-id"]);
$eventBus.emit(
"authenticated-by-modal",
route.query["invite-id"]
);
}
// if redirected from chat system to relogin.
else {
@ -81,10 +86,12 @@ export default {
}
})
.catch((err) => {
mySwalToast({
toast.add({
title: err.message,
icon: "error",
timer: 2000,
});
this.resetCaptcha();
})
.finally(() => {

View File

@ -2,6 +2,11 @@
import fs from "fs-extra";
import path from "path";
import chat from "./routes/chat";
import haditha from "./routes/haditha";
import search from "./routes/search";
import research from "./routes/research";
const envs = import.meta.env;
let sassEnvVariables = "";
@ -13,13 +18,6 @@ for (let e in envs) {
// dynamically importing styles.
const buildName = import.meta.env.VITE_BUILD_NAME;
let mainStyle = `~/assets/common/scss/${buildName}-styles.scss`;
if (buildName == "haditha")
mainStyle = `~/systems/${buildName.substring(
0,
buildName.length - 1
)}_ui/assets/${buildName}/scss/${buildName}.css`;
export default defineNuxtConfig({
hooks: {
@ -46,109 +44,7 @@ export default defineNuxtConfig({
"pages:extend"(pages) {
// Add custom routes
pages.push(
{
name: "search",
path: "/search",
file: "~/systems/search_ui/pages/search/index.vue",
},
{
name: "searchNavigation",
path: "/search/lists",
file: "~/systems/search_ui/pages/search/lists.vue",
},
{
name: "searchChart",
path: "/search/charts",
file: "~/systems/search_ui/pages/search/charts.vue",
},
{
name: "showEntity",
path: "/search/:key/:id/show",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "navigationView",
path: "/search/:key/:id/list",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/research",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/detail",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
// --------------------- start: Research routes ---------------------
{
name: "myResearches",
path: "/research/research-home",
file: "~/systems/research_ui/pages/index.vue",
},
{
name: "TermPage",
path: "/research/research-term",
file: "~/systems/research_ui/pages/TermPage.vue",
},
// --------------------- end: Research routes ---------------------
// --------------------- start: haditha routes ---------------------
{
name: "haditha",
path: "/haditha",
file: "~/systems/hadith_ui/pages/haditha/index.vue",
},
{
name: "hadithaSearch",
path: "/haditha/search",
file: "~/systems/hadith_ui/pages/haditha/search/index.vue",
},
{
name: "hadithaChatBot",
path: "/haditha/chat-bot",
file: "~/systems/hadith_ui/pages/haditha/chat-bot.vue",
},
{
name: "hadithaFavorites",
path: "/haditha/favorites",
file: "~/systems/hadith_ui/pages/haditha/favorites/index.vue",
},
{
name: "hadithaLibrary",
path: "/haditha/library",
file: "~/systems/hadith_ui/pages/haditha/library/index.vue",
},
{
name: "hadithaLibraryShow",
path: "/haditha/library/:id/:slug?",
file: "~/systems/hadith_ui/pages/haditha/library/[id]/[slug]/index.vue",
},
{
name: "hadithaAbout",
path: "/haditha/about-us",
file: "~/systems/hadith_ui/pages/haditha/public-pages/about-us.vue",
},
{
name: "hadithaContact",
path: "/haditha/contact-us",
file: "~/systems/hadith_ui/pages/haditha/public-pages/ContactUs.vue",
},
{
name: "hadithaRules",
path: "/haditha/rules",
file: "~/systems/hadith_ui/pages/haditha/public-pages/rules.vue",
},
{
name: "hadithaLogin",
path: "/haditha/login",
file: "~/systems/hadith_ui/pages/haditha/login.vue",
}
// --------------------- end: haditha routes ---------------------
);
pages.push(...search, ...research, ...haditha, ...chat);
},
},
@ -252,7 +148,7 @@ export default defineNuxtConfig({
},
},
css: [
mainStyle,
customStyleLoader(),
// "vue3-persian-datetime-picker/src/picker/assets/scss/style.scss",
],
alias: {
@ -273,6 +169,7 @@ export default defineNuxtConfig({
"@search": "~/systems/search_ui",
"@research": "~/systems/research_ui",
"@haditha": "~/systems/hadith_ui",
"@chat": "~/systems/chat_ui",
},
vite: {
resolve: {},
@ -442,3 +339,13 @@ export default defineNuxtConfig({
// console.log(runtimeConfig.public.apiBase)
// Resolve ~, ~~, @ and @@ aliases located within layers with respect to their layer source and root directories.
function customStyleLoader() {
let mainStyle = `~/assets/common/scss/${buildName}-styles.scss`;
if (buildName == "haditha")
mainStyle = `~/systems/${buildName.substring(
0,
buildName.length - 1
)}_ui/assets/${buildName}/scss/${buildName}.css`;
return mainStyle;
}

148
package-lock.json generated
View File

@ -18,6 +18,7 @@
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"codemirror": "^6.0.1",
"cropperjs": "^2.0.0",
"docx": "^9.1.1",
"echarts": "^5.5.1",
"echarts-wordcloud": "^2.1.0",
@ -45,6 +46,7 @@
"vue-draggable-next": "^2.2.1",
"vue-echarts": "^7.0.3",
"vue-i18n": "^10.0.1",
"vue-image-upload-resize": "^2.3.0",
"vue-jalali-moment": "^1.0.0",
"vue-jstree": "^2.1.6",
"vue-multiselect": "^3.0.0",
@ -751,6 +753,126 @@
"w3c-keyname": "^2.2.4"
}
},
"node_modules/@cropper/element": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element/-/element-2.0.0.tgz",
"integrity": "sha512-lsthn0nQq73GExUE7Mg/ss6Q3RXADGDv055hxoLFwvl/wGHgy6ZkYlfLZ/VmgBHC6jDK5IgPBFnqrPqlXWSGBA==",
"license": "MIT",
"dependencies": {
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-canvas": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-canvas/-/element-canvas-2.0.0.tgz",
"integrity": "sha512-GPtGJgSm92crJhhhwUsaMw3rz2KfJWWSz7kRAlufFEV/EHTP5+6r6/Z1BCGRna830i+Avqbm435XLOtA7PVJwA==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-crosshair": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-crosshair/-/element-crosshair-2.0.0.tgz",
"integrity": "sha512-KfPfyrdeFvUC31Ws7ATtcalWWSaMtrC6bMoCipZhqbUOE7wZoL4ecDSL6BUOZxPa74awZUqfzirCDjHvheBfyw==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-grid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-grid/-/element-grid-2.0.0.tgz",
"integrity": "sha512-i78SQ0IJTLFveKX6P7svkfMYVdgHrQ8ZmmEw8keFy9n1ZVbK+SK0UHK5FNMRNI/gtVhKJOGEnK/zeyjUdj4Iyw==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-handle": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-handle/-/element-handle-2.0.0.tgz",
"integrity": "sha512-ZJvW+0MkK9E8xYymGdoruaQn2kwjSHFpNSWinjyq6csuVQiCPxlX5ovAEDldmZ9MWePPtWEi3vLKQOo2Yb0T8g==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-image": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-image/-/element-image-2.0.0.tgz",
"integrity": "sha512-9BxiTS/aHRmrjopaFQb9mQQXmx4ruhYHGkDZMVz24AXpMFjUY6OpqrWse/WjzD9tfhMFvEdu17b3VAekcAgpeg==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/element-canvas": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-selection": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-selection/-/element-selection-2.0.0.tgz",
"integrity": "sha512-ensNnbIfJsJ8bhbJTH/RXtk2URFvTOO4TvfRk461n2FPEC588D7rwBmUJxQg74IiTi4y1JbCI+6j+4LyzYBLCQ==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/element-canvas": "^2.0.0",
"@cropper/element-image": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-shade": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-shade/-/element-shade-2.0.0.tgz",
"integrity": "sha512-jv/2bbNZnhU4W+T4G0c8ADocLIZvQFTXgCf2RFDNhI5UVxurzWBnDdb8Mx8LnVplnkTqO+xUmHZYve0CwgWo+Q==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/element-canvas": "^2.0.0",
"@cropper/element-selection": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/element-viewer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/element-viewer/-/element-viewer-2.0.0.tgz",
"integrity": "sha512-zY+3VRN5TvpM8twlphYtXw0tzJL2VgzeK7ufhL1BixVqOdRxwP13TprYIhqwGt9EW/SyJZUiaIu396T89kRX8A==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/element-canvas": "^2.0.0",
"@cropper/element-image": "^2.0.0",
"@cropper/element-selection": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/@cropper/elements": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/elements/-/elements-2.0.0.tgz",
"integrity": "sha512-PQkPo1nUjxLFUQuHYu+6atfHxpX9B41Xribao6wpvmvmNIFML6LQdNqqWYb6LyM7ujsu71CZdBiMT5oetjJVoQ==",
"license": "MIT",
"dependencies": {
"@cropper/element": "^2.0.0",
"@cropper/element-canvas": "^2.0.0",
"@cropper/element-crosshair": "^2.0.0",
"@cropper/element-grid": "^2.0.0",
"@cropper/element-handle": "^2.0.0",
"@cropper/element-image": "^2.0.0",
"@cropper/element-selection": "^2.0.0",
"@cropper/element-shade": "^2.0.0",
"@cropper/element-viewer": "^2.0.0"
}
},
"node_modules/@cropper/utils": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@cropper/utils/-/utils-2.0.0.tgz",
"integrity": "sha512-cprLYr+7kK3faGgoOsTW9gIn5sefDr2KwOmgyjzIXk+8PLpW8FgFKEg5FoWfRD5zMAmkCBuX6rGKDK3VdUEGrg==",
"license": "MIT"
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.24.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
@ -6325,6 +6447,12 @@
"integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
"license": "MIT"
},
"node_modules/blueimp-canvas-to-blob": {
"version": "3.29.0",
"resolved": "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz",
"integrity": "sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg==",
"license": "MIT"
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@ -7154,6 +7282,16 @@
"cronstrue": "bin/cli.js"
}
},
"node_modules/cropperjs": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-2.0.0.tgz",
"integrity": "sha512-TO2j0Qre01kPHbow4FuTrbdEB4jTmGRySxW49jyEIqlJZuEBfrvCTT0vC3eRB2WBXudDfKi1Onako6DKWKxeAQ==",
"license": "MIT",
"dependencies": {
"@cropper/elements": "^2.0.0",
"@cropper/utils": "^2.0.0"
}
},
"node_modules/cross-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
@ -20446,6 +20584,16 @@
"vue": "^3.0.0"
}
},
"node_modules/vue-image-upload-resize": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/vue-image-upload-resize/-/vue-image-upload-resize-2.3.0.tgz",
"integrity": "sha512-ElzyAVCluiDt8xSZkSK9FbuLY5mr23JlO4cHyyRo86RfEGLWtvXrTq7vYOgDstT8rNBmnTgNCkPKc0rpmyl1yA==",
"license": "MIT",
"dependencies": {
"blueimp-canvas-to-blob": "^3.14.0",
"vue": "^2.5.17"
}
},
"node_modules/vue-jalali-moment": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vue-jalali-moment/-/vue-jalali-moment-1.0.0.tgz",

View File

@ -26,6 +26,7 @@
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"codemirror": "^6.0.1",
"cropperjs": "^2.0.0",
"docx": "^9.1.1",
"echarts": "^5.5.1",
"echarts-wordcloud": "^2.1.0",
@ -53,6 +54,7 @@
"vue-draggable-next": "^2.2.1",
"vue-echarts": "^7.0.3",
"vue-i18n": "^10.0.1",
"vue-image-upload-resize": "^2.3.0",
"vue-jalali-moment": "^1.0.0",
"vue-jstree": "^2.1.6",
"vue-multiselect": "^3.0.0",

64
routes/chat.ts Normal file
View File

@ -0,0 +1,64 @@
export default [
{
path: "/chat",
file: "@chat/pages/index.vue",
children: [
{
path: "",
redirect: { name: "unReads" },
},
{
path: "all/list",
name: "all",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "همه",
},
},
{
path: "privates/list",
name: "privates",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "خصوصی ها",
},
},
{
path: "groups/list",
name: "groups",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "گروه ها",
},
},
{
path: "lobbies/list",
name: "lobbies",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "تالارها",
},
},
{
path: "unreads/list",
name: "unReads",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "نخوانده",
},
},
{
path: "my-messages/list",
name: "myMessages",
file: "@chat/pages/Chat.vue",
meta: {
breadcrumb: "پیام های من",
},
},
],
},
];

53
routes/haditha.ts Normal file
View File

@ -0,0 +1,53 @@
export default [
{
name: "haditha",
path: "/haditha",
file: "~/systems/hadith_ui/pages/haditha/index.vue",
},
{
name: "hadithaSearch",
path: "/haditha/search",
file: "~/systems/hadith_ui/pages/haditha/search/index.vue",
},
{
name: "hadithaChatBot",
path: "/haditha/chat-bot",
file: "~/systems/hadith_ui/pages/haditha/chat-bot.vue",
},
{
name: "hadithaFavorites",
path: "/haditha/favorites",
file: "~/systems/hadith_ui/pages/haditha/favorites/index.vue",
},
{
name: "hadithaLibrary",
path: "/haditha/library",
file: "~/systems/hadith_ui/pages/haditha/library/index.vue",
},
{
name: "hadithaLibraryShow",
path: "/haditha/library/:id/:slug?",
file: "~/systems/hadith_ui/pages/haditha/library/[id]/[slug]/index.vue",
},
{
name: "hadithaAbout",
path: "/haditha/about-us",
file: "~/systems/hadith_ui/pages/haditha/public-pages/about-us.vue",
},
{
name: "hadithaContact",
path: "/haditha/contact-us",
file: "~/systems/hadith_ui/pages/haditha/public-pages/ContactUs.vue",
},
{
name: "hadithaRules",
path: "/haditha/rules",
file: "~/systems/hadith_ui/pages/haditha/public-pages/rules.vue",
},
// {
// name: "hadithaLogin",
// path: "/haditha/login",
// file: "~/systems/hadith_ui/pages/haditha/login.vue",
// }
];

12
routes/research.ts Normal file
View File

@ -0,0 +1,12 @@
export default [
{
name: "myResearches",
path: "/research/research-home",
file: "~/systems/research_ui/pages/index.vue",
},
{
name: "TermPage",
path: "/research/research-term",
file: "~/systems/research_ui/pages/TermPage.vue",
},
];

37
routes/search.ts Normal file
View File

@ -0,0 +1,37 @@
export default [
{
name: "search",
path: "/search",
file: "~/systems/search_ui/pages/search/index.vue",
},
{
name: "searchNavigation",
path: "/search/lists",
file: "~/systems/search_ui/pages/search/lists.vue",
},
{
name: "searchChart",
path: "/search/charts",
file: "~/systems/search_ui/pages/search/charts.vue",
},
{
name: "showEntity",
path: "/search/:key/:id/show",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "navigationView",
path: "/search/:key/:id/list",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/research",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
{
name: "entityResearch",
path: "/search/:key/:id/detail",
file: "~/systems/search_ui/pages/search/(show)/[key]/[id]/index.vue",
},
];

30
server/api/upload.post.ts Normal file
View File

@ -0,0 +1,30 @@
import { defineEventHandler, readMultipartFormData } from "h3";
import { promises as fs } from "fs";
import sharp from "sharp";
export default defineEventHandler(async (event) => {
const files = await readMultipartFormData(event);
if (!files || files.length === 0) {
return { error: "No files uploaded" };
}
const uploadedFile = files[0];
const fileName = `cropped-${Date.now()}.png`;
const filePath = `./public/uploads/${fileName}`;
// Save the cropped image
await fs.writeFile(filePath, uploadedFile.data);
// Optionally resize the image
const resizedFilePath = `./public/uploads/resized-${fileName}`;
await sharp(uploadedFile.data)
.resize(300, 300) // Adjust dimensions as needed
.toFile(resizedFilePath);
return {
message: "File uploaded successfully",
originalFile: `/uploads/${fileName}`,
resizedFile: `/uploads/resized-${fileName}`,
};
});

View File

@ -66,9 +66,7 @@ export const useCommonStore = defineStore("commonStore", {
userLastState: null,
schemas: {} as Schemas,
activeSchema: {} as ActiveSchema,
forwardItem: {} as ForwardItem,
selectedlists: {} as Selectedlists,
sidebarListStatus: false,
userHistory: {},
lastRecord: {} as lastRecord | undefined,
@ -122,7 +120,6 @@ export const useCommonStore = defineStore("commonStore", {
repoMircroServiceName: () => import.meta.env.VITE_REPO,
logMircroServiceName: () => import.meta.env.VITE_LOG,
listMircroServiceName: () => import.meta.env.VITE_LIST,
getForwardItem: (state) => state.forwardItem,
activeSchemaGetter: (state) => state.activeSchema,
schemasGetter: (state) => state.schemas,
organNameGetter: () => import.meta.env.VITE_BUILD_NAME,
@ -142,7 +139,6 @@ export const useCommonStore = defineStore("commonStore", {
isDesktopGetter: (state) => state.isDesktop,
isMobileGetter: (state) => state.isMobile,
selectedlistsGetter: (state) => state.selectedlists,
sidebarListStatusGetter: (state) => state.sidebarListStatus,
sidebarMenuGetter: (state) => state.sidebarMenu,
userHistoryGetter: (state) => state.userHistory,
lastRecordGetter: (state) => state.lastRecord,
@ -189,9 +185,7 @@ export const useCommonStore = defineStore("commonStore", {
this.collapsed = isCollapsed;
},
SET_FORWARD_ITEM(forwardItem: ForwardItem) {
this.forwardItem = forwardItem;
},
SET_SECTIONS(jahatSection: JahatSection) {
this.jahatSection = jahatSection;
},
@ -232,12 +226,6 @@ export const useCommonStore = defineStore("commonStore", {
this.selectedlists = selectedlists;
},
// SET_SIDEBAR_LIST_STATUS(newState = undefined) {
// this.sidebarListStatus =
// newState != undefined || newState != null
// ? newState
// : !this.sidebarListStatus;
// },
SET_AUTHORIZED_PAGES(pages: Permission[] = []) {
const AuthorizedPages: Set<string> = new Set();
@ -266,14 +254,7 @@ export const useCommonStore = defineStore("commonStore", {
clearUser() {
this.$reset();
},
chatSidebarListStatusReactor(newState: boolean) {
// this.SET_SIDEBAR_LIST_STATUS = newVal;
this.sidebarListStatus =
newState != undefined || newState != null
? newState
: !this.sidebarListStatus;
},
async getState() {
const settingsApi = (await import("~/apis/adminApi")).default;

1
systems/chat_ui Submodule

@ -0,0 +1 @@
Subproject commit 2a5f878608e9cc9e508ab4de70337c2673344596

View File

@ -4,6 +4,7 @@ import { convertEnToPe } from "~/manuals/persianNumber";
// import Cookies from "js-cookie";
import { useCommonStore } from "~/stores/commonStore";
import { useAuthStore } from "~/stores/authStore";
import { isValidHttpUrl } from "~/manuals/utilities";
// // ...mapState("common", ["activeSystemGetter"]),
export const appDescription = () => {
@ -347,7 +348,7 @@ export const redirectToRouteName = (routeName = "dashboard") => {
// clearBodyClass();
});
};
export const getGroupAvatar = (user = undefined) => {
export const getGroupAvatar = async (user = undefined) => {
try {
if (user) {
if (isValidHttpUrl(user.avatar)) return user.avatar;
@ -365,7 +366,7 @@ export const getGroupAvatar = (user = undefined) => {
}
}
} catch (err) {
return import("~/assets/common/img/default.svg").default;
return (await import("~/assets/common/img/default.svg")).default;
}
};
export const convertUnixToPersianDateTime = (created_at) => {

120
yarn.lock
View File

@ -381,6 +381,105 @@
style-mod "^4.1.0"
w3c-keyname "^2.2.4"
"@cropper/element-canvas@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-canvas/-/element-canvas-2.0.0.tgz"
integrity sha512-GPtGJgSm92crJhhhwUsaMw3rz2KfJWWSz7kRAlufFEV/EHTP5+6r6/Z1BCGRna830i+Avqbm435XLOtA7PVJwA==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-crosshair@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-crosshair/-/element-crosshair-2.0.0.tgz"
integrity sha512-KfPfyrdeFvUC31Ws7ATtcalWWSaMtrC6bMoCipZhqbUOE7wZoL4ecDSL6BUOZxPa74awZUqfzirCDjHvheBfyw==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-grid@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-grid/-/element-grid-2.0.0.tgz"
integrity sha512-i78SQ0IJTLFveKX6P7svkfMYVdgHrQ8ZmmEw8keFy9n1ZVbK+SK0UHK5FNMRNI/gtVhKJOGEnK/zeyjUdj4Iyw==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-handle@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-handle/-/element-handle-2.0.0.tgz"
integrity sha512-ZJvW+0MkK9E8xYymGdoruaQn2kwjSHFpNSWinjyq6csuVQiCPxlX5ovAEDldmZ9MWePPtWEi3vLKQOo2Yb0T8g==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-image@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-image/-/element-image-2.0.0.tgz"
integrity sha512-9BxiTS/aHRmrjopaFQb9mQQXmx4ruhYHGkDZMVz24AXpMFjUY6OpqrWse/WjzD9tfhMFvEdu17b3VAekcAgpeg==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/element-canvas" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-selection@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-selection/-/element-selection-2.0.0.tgz"
integrity sha512-ensNnbIfJsJ8bhbJTH/RXtk2URFvTOO4TvfRk461n2FPEC588D7rwBmUJxQg74IiTi4y1JbCI+6j+4LyzYBLCQ==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/element-canvas" "^2.0.0"
"@cropper/element-image" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-shade@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-shade/-/element-shade-2.0.0.tgz"
integrity sha512-jv/2bbNZnhU4W+T4G0c8ADocLIZvQFTXgCf2RFDNhI5UVxurzWBnDdb8Mx8LnVplnkTqO+xUmHZYve0CwgWo+Q==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/element-canvas" "^2.0.0"
"@cropper/element-selection" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element-viewer@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element-viewer/-/element-viewer-2.0.0.tgz"
integrity sha512-zY+3VRN5TvpM8twlphYtXw0tzJL2VgzeK7ufhL1BixVqOdRxwP13TprYIhqwGt9EW/SyJZUiaIu396T89kRX8A==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/element-canvas" "^2.0.0"
"@cropper/element-image" "^2.0.0"
"@cropper/element-selection" "^2.0.0"
"@cropper/utils" "^2.0.0"
"@cropper/element@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/element/-/element-2.0.0.tgz"
integrity sha512-lsthn0nQq73GExUE7Mg/ss6Q3RXADGDv055hxoLFwvl/wGHgy6ZkYlfLZ/VmgBHC6jDK5IgPBFnqrPqlXWSGBA==
dependencies:
"@cropper/utils" "^2.0.0"
"@cropper/elements@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/elements/-/elements-2.0.0.tgz"
integrity sha512-PQkPo1nUjxLFUQuHYu+6atfHxpX9B41Xribao6wpvmvmNIFML6LQdNqqWYb6LyM7ujsu71CZdBiMT5oetjJVoQ==
dependencies:
"@cropper/element" "^2.0.0"
"@cropper/element-canvas" "^2.0.0"
"@cropper/element-crosshair" "^2.0.0"
"@cropper/element-grid" "^2.0.0"
"@cropper/element-handle" "^2.0.0"
"@cropper/element-image" "^2.0.0"
"@cropper/element-selection" "^2.0.0"
"@cropper/element-shade" "^2.0.0"
"@cropper/element-viewer" "^2.0.0"
"@cropper/utils@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@cropper/utils/-/utils-2.0.0.tgz"
integrity sha512-cprLYr+7kK3faGgoOsTW9gIn5sefDr2KwOmgyjzIXk+8PLpW8FgFKEg5FoWfRD5zMAmkCBuX6rGKDK3VdUEGrg==
"@esbuild/win32-x64@0.21.5":
version "0.21.5"
resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz"
@ -2844,6 +2943,11 @@ bluebird@~3.4.0:
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz"
integrity sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==
blueimp-canvas-to-blob@^3.14.0:
version "3.29.0"
resolved "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz"
integrity sha512-0pcSSGxC0QxT+yVkivxIqW0Y4VlO2XSDPofBAqoJ1qJxgH9eiUDLv50Rixij2cDuEfx4M6DpD9UGZpRhT5Q8qg==
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz"
@ -3426,6 +3530,14 @@ cronstrue@^2.52.0:
resolved "https://registry.npmjs.org/cronstrue/-/cronstrue-2.54.0.tgz"
integrity sha512-vyp5NklDxA5MjPfQgkn0bA+0vRQe7Q9keX7RPdV6rMgd7LtDvbuKgnT+3T5ZAX16anSP5HmahcRp8mziXsLfaw==
cropperjs@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/cropperjs/-/cropperjs-2.0.0.tgz"
integrity sha512-TO2j0Qre01kPHbow4FuTrbdEB4jTmGRySxW49jyEIqlJZuEBfrvCTT0vC3eRB2WBXudDfKi1Onako6DKWKxeAQ==
dependencies:
"@cropper/elements" "^2.0.0"
"@cropper/utils" "^2.0.0"
cross-fetch@^3.0.4:
version "3.2.0"
resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz"
@ -9418,6 +9530,14 @@ vue-i18n@*, vue-i18n@^10.0.0, vue-i18n@^10.0.1, vue-i18n@^10.0.3:
"@intlify/shared" "10.0.4"
"@vue/devtools-api" "^6.5.0"
vue-image-upload-resize@^2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/vue-image-upload-resize/-/vue-image-upload-resize-2.3.0.tgz"
integrity sha512-ElzyAVCluiDt8xSZkSK9FbuLY5mr23JlO4cHyyRo86RfEGLWtvXrTq7vYOgDstT8rNBmnTgNCkPKc0rpmyl1yA==
dependencies:
blueimp-canvas-to-blob "^3.14.0"
vue "^2.5.17"
vue-jalali-moment@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/vue-jalali-moment/-/vue-jalali-moment-1.0.0.tgz"