Compare commits
30 Commits
baghi/base
...
main
Author | SHA1 | Date | |
---|---|---|---|
f5c54cd632 | |||
![]() |
3ee869a66b | ||
![]() |
b21c8549ab | ||
![]() |
851324eb0b | ||
![]() |
1ccf9e09ba | ||
![]() |
f2fee4c45f | ||
![]() |
f00f10ca3d | ||
![]() |
0f155d2f04 | ||
![]() |
1cae9689c5 | ||
![]() |
d1373fb94c | ||
![]() |
be39f7377b | ||
![]() |
16bb8986e0 | ||
![]() |
4f6e31fed7 | ||
![]() |
5ee08b4c7a | ||
![]() |
5f2c8ba4e0 | ||
![]() |
5100db79da | ||
![]() |
ab00e04dd8 | ||
![]() |
c71b5737cd | ||
![]() |
95b2b62095 | ||
![]() |
ca6372b438 | ||
![]() |
cab508f69a | ||
![]() |
19a83a6367 | ||
![]() |
47d58ecdf4 | ||
![]() |
fc1d8b6109 | ||
![]() |
0d0fd2dacd | ||
![]() |
606d3bdc05 | ||
![]() |
436ab75d21 | ||
![]() |
61f02d6883 | ||
![]() |
e7bbe4d628 | ||
![]() |
48320d52af |
|
@ -1,5 +1,5 @@
|
||||||
VITE_API_NAME=api/
|
NUXT_PUBLIC_API_NAME=api/
|
||||||
VITE_BASE_URL=http://192.168.23.60/
|
NUXT_PUBLIC_BASE_URL=http://192.168.23.60/
|
||||||
|
|
||||||
VITE_APP_NAME=Hadith
|
VITE_APP_NAME=Hadith
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ VITE_APP_NAME=Hadith
|
||||||
### Relative pathes for systems sass addressing ###
|
### Relative pathes for systems sass addressing ###
|
||||||
# 0 : majles.tavasi.ir 1: qanon.parliran.ir
|
# 0 : majles.tavasi.ir 1: qanon.parliran.ir
|
||||||
VITE_BUILD_STATE=0
|
VITE_BUILD_STATE=0
|
||||||
VITE_BUILD_NAME=hadith
|
VITE_BUILD_NAME=haditha
|
||||||
|
|
||||||
VITE_IDB_NAME=hadith
|
VITE_IDB_NAME=haditha
|
||||||
VITE_IDB_VERSION=1
|
VITE_IDB_VERSION=1
|
||||||
VITE_ENABLE_IDB=1
|
VITE_ENABLE_IDB=1
|
||||||
|
|
3
.gitmodules
vendored
|
@ -7,3 +7,6 @@
|
||||||
[submodule "systems/hadith_ui"]
|
[submodule "systems/hadith_ui"]
|
||||||
path = systems/hadith_ui
|
path = systems/hadith_ui
|
||||||
url = https://git2.tavasi.ir/front/hadith_ui.git
|
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
|
||||||
|
|
289
COMPOSITION_API.md
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
1. Organize Your Code into Logical Sections
|
||||||
|
|
||||||
|
Structure your component script into clear sections to improve readability. A common approach is to group related logic together.
|
||||||
|
Example Structure:
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 1. Imports
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
// 2. Reactive State
|
||||||
|
const count = ref(0)
|
||||||
|
const name = ref('')
|
||||||
|
|
||||||
|
// 3. Computed Properties
|
||||||
|
const doubledCount = computed(() => count.value * 2)
|
||||||
|
|
||||||
|
// 4. Functions / Methods
|
||||||
|
function increment() {
|
||||||
|
count.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Lifecycle Hooks
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('Component mounted')
|
||||||
|
})
|
||||||
|
|
||||||
|
// 6. Watchers
|
||||||
|
watch(count, (newValue, oldValue) => {
|
||||||
|
console.log(`Count changed from ${oldValue} to ${newValue}`)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
2. Use script setup Syntax
|
||||||
|
|
||||||
|
The <script setup> syntax is the recommended way to write Composition API components. It provides a more concise and intuitive syntax.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const message = ref('Hello, Vue 3!')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<p>{{ message }}</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
3. Use Descriptive Variable and Function Names
|
||||||
|
|
||||||
|
Choose meaningful names for variables, functions, and computed properties to make your code self-documenting.
|
||||||
|
Example:
|
||||||
|
// Bad
|
||||||
|
const x = ref(0)
|
||||||
|
|
||||||
|
// Good
|
||||||
|
const userCount = ref(0)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
4. Extract Reusable Logic into Composables
|
||||||
|
Move reusable logic into composables (custom hooks) to keep your components clean and promote code reuse.
|
||||||
|
Example Composable:
|
||||||
|
|
||||||
|
// composables/useCounter.js
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export function useCounter(initialValue = 0) {
|
||||||
|
const count = ref(initialValue)
|
||||||
|
|
||||||
|
function increment() {
|
||||||
|
count.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
count.value = initialValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
count,
|
||||||
|
increment,
|
||||||
|
reset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Usage in a Component:
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useCounter } from '~/composables/useCounter'
|
||||||
|
|
||||||
|
const { count, increment } = useCounter()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<p>Count: {{ count }}</p>
|
||||||
|
<button @click="increment">Increment</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
5. Use ref for Primitive Values and reactive for Objects
|
||||||
|
|
||||||
|
- Use ref for primitive values (e.g., numbers, strings, booleans).
|
||||||
|
- Use reactive for objects or arrays.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
const count = ref(0) // Primitive value
|
||||||
|
const user = reactive({ name: 'John', age: 30 }) // Object
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
6. Use Computed Properties for Derived State
|
||||||
|
|
||||||
|
Use computed to create reactive properties that depend on other state. This ensures the derived state is always up-to-date.
|
||||||
|
Example:
|
||||||
|
const firstName = ref('John')
|
||||||
|
const lastName = ref('Doe')
|
||||||
|
|
||||||
|
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
7. Use Watchers Sparingly
|
||||||
|
|
||||||
|
Watchers (watch and watchEffect) are powerful but can make your code harder to understand if overused. Prefer computed properties or event-driven updates where possible.
|
||||||
|
Example:
|
||||||
|
watch(count, (newValue, oldValue) => {
|
||||||
|
console.log(`Count changed from ${oldValue} to ${newValue}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
8. Group Related Logic Together
|
||||||
|
|
||||||
|
Keep related reactive state, computed properties, and functions together to make your code easier to follow.
|
||||||
|
Example:
|
||||||
|
// User-related logic
|
||||||
|
const user = reactive({ name: 'John', age: 30 })
|
||||||
|
const isAdult = computed(() => user.age >= 18)
|
||||||
|
function updateUser(newName) {
|
||||||
|
user.name = newName
|
||||||
|
}
|
||||||
|
|
||||||
|
-----------
|
||||||
|
|
||||||
|
9. Use Lifecycle Hooks for Side Effects
|
||||||
|
|
||||||
|
Use lifecycle hooks (onMounted, onUnmounted, etc.) for side effects like fetching data or setting up event listeners.
|
||||||
|
Example:
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('Component mounted')
|
||||||
|
fetchData()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
console.log('Component unmounted')
|
||||||
|
cleanup()
|
||||||
|
})
|
||||||
|
|
||||||
|
----------------
|
||||||
|
|
||||||
|
10. Use TypeScript for Better Type Safety
|
||||||
|
If your project uses TypeScript, leverage it to add type safety to your components.
|
||||||
|
Example:
|
||||||
|
<script setup lang="ts">
|
||||||
|
interface User {
|
||||||
|
name: string
|
||||||
|
age: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = ref<User>({ name: 'John', age: 30 })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
--------------
|
||||||
|
|
||||||
|
11. Keep Templates Clean
|
||||||
|
|
||||||
|
Avoid putting too much logic in your template. Instead, move complex logic into the script or composables.
|
||||||
|
Example:
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p>{{ fullName }}</p>
|
||||||
|
<button @click="increment">Increment</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const firstName = ref('John')
|
||||||
|
const lastName = ref('Doe')
|
||||||
|
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
|
||||||
|
|
||||||
|
function increment() {
|
||||||
|
// Logic here
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
12. Use provide and inject for Prop Drilling
|
||||||
|
Avoid prop drilling by using provide and inject to share state across deeply nested components.
|
||||||
|
Example:
|
||||||
|
// Parent component
|
||||||
|
import { provide, ref } from 'vue'
|
||||||
|
|
||||||
|
const theme = ref('dark')
|
||||||
|
provide('theme', theme)
|
||||||
|
|
||||||
|
// Child component
|
||||||
|
import { inject } from 'vue'
|
||||||
|
|
||||||
|
const theme = inject('theme')
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
13. Use v-model for Two-Way Binding
|
||||||
|
|
||||||
|
Use v-model to simplify two-way binding between parent and child components.
|
||||||
|
Example:
|
||||||
|
<!-- Parent component -->
|
||||||
|
<template>
|
||||||
|
<ChildComponent v-model:name="userName" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const userName = ref('John')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Child component -->
|
||||||
|
<template>
|
||||||
|
<input :value="name" @input="$emit('update:name', $event.target.value)" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
defineProps(['name'])
|
||||||
|
defineEmits(['update:name'])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
14. Use defineProps and defineEmits for TypeScript Support
|
||||||
|
|
||||||
|
When using TypeScript, use defineProps and defineEmits to define props and emits with type safety.
|
||||||
|
Example:
|
||||||
|
<script setup lang="ts">
|
||||||
|
const props = defineProps<{
|
||||||
|
title: string
|
||||||
|
count: number
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(event: 'update:count', value: number): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
-------------
|
||||||
|
|
||||||
|
15. Use Scoped Styles
|
||||||
|
|
||||||
|
Use scoped styles (<style scoped>) to ensure styles are component-specific and don’t leak into other components.
|
||||||
|
Example:
|
||||||
|
<style scoped>
|
||||||
|
.button {
|
||||||
|
background-color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
|
16. Use Environment Variables
|
||||||
|
|
||||||
|
Use environment variables for configuration (e.g., API URLs) to keep your code flexible and secure.
|
||||||
|
Example:
|
||||||
|
const apiUrl = import.meta.env.VITE_API_URL
|
||||||
|
|
||||||
|
-------------
|
||||||
|
|
||||||
|
17. Write Unit Tests
|
||||||
|
|
||||||
|
Write unit tests for your components and composables to ensure they work as expected.
|
||||||
|
Example:
|
||||||
|
import { render } from '@testing-library/vue'
|
||||||
|
import MyComponent from '@/components/MyComponent.vue'
|
||||||
|
|
||||||
|
test('renders correctly', () => {
|
||||||
|
const { getByText } = render(MyComponent)
|
||||||
|
expect(getByText('Hello, Vue 3!')).toBeInTheDocument()
|
||||||
|
})
|
52
GIT_SUBMODULE.md
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
## How to Remove an Existing Submodule
|
||||||
|
|
||||||
|
If the path was previously added as a submodule, you need to remove it completely before re-adding it. Follow these steps:
|
||||||
|
|
||||||
|
1. Remove the submodule entry from .gitmodules.
|
||||||
|
2. Remove the submodule from the working tree and index: git rm --cached <path-to-submodule>.
|
||||||
|
3. Delete the submodule directory: rm -rf <path-to-submodule>.
|
||||||
|
4. Stage the .gitmodules changes: git add .gitmodules.
|
||||||
|
5. Commit the changes: git commit -m "Removed submodule <submodule-name>".
|
||||||
|
|
||||||
|
errors:
|
||||||
|
|
||||||
|
# repo already exists and is not a valid git repo
|
||||||
|
|
||||||
|
Check if the path is already tracked
|
||||||
|
git ls-files --stage systems/chat_ui (100644 <hash> 0 <path>)
|
||||||
|
|
||||||
|
If it is, remove it from the index
|
||||||
|
git rm --cached systems/chat_ui
|
||||||
|
|
||||||
|
If system/chat_ui exits, remote it(chat_ui)
|
||||||
|
rm -r systems/chat_ui
|
||||||
|
|
||||||
|
Add the submodule
|
||||||
|
git submodule add https://github.com/example/repo.git systems/chat_ui
|
||||||
|
|
||||||
|
Commit the changes
|
||||||
|
git commit -m "Added submodule at systems/chat_ui"
|
||||||
|
|
||||||
|
Verify the submodule
|
||||||
|
git submodule status
|
||||||
|
|
||||||
|
(Optional) Initialize and Update the Submodule
|
||||||
|
If the submodule was added successfully but not initialized, run:
|
||||||
|
git submodule update --init --recursive
|
26
app.vue
|
@ -2,33 +2,23 @@
|
||||||
<UApp :locale="fa_ir">
|
<UApp :locale="fa_ir">
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
<NuxtRouteAnnouncer />
|
<NuxtRouteAnnouncer />
|
||||||
<!-- <DevOnly> -->
|
|
||||||
<!-- this component will only be rendered during development -->
|
|
||||||
<!-- <LazyDebugBar /> -->
|
|
||||||
|
|
||||||
<!-- if you ever require to have a replacement during production -->
|
|
||||||
<!-- be sure to test these using `nuxt preview` -->
|
|
||||||
<!-- <template #fallback> -->
|
|
||||||
<!-- <div>empty div for flex.justify-between</div> -->
|
|
||||||
<!-- </template> -->
|
|
||||||
<!-- </DevOnly> -->
|
|
||||||
|
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<!-- this component will be rendered on client-side -->
|
|
||||||
<!-- <NuxtClientFallback
|
|
||||||
fallback-tag="span"
|
|
||||||
fallback="NuxtClientFallback"
|
|
||||||
@ssr-error="logSomeError"
|
|
||||||
> -->
|
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
<!-- <BrokeInSsr /> -->
|
|
||||||
<!-- </NuxtClientFallback> -->
|
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</UApp>
|
</UApp>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { fa_ir } from "@nuxt/ui/locale";
|
import { fa_ir } from "@nuxt/ui/locale";
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// const toast = useToast();
|
||||||
|
// toast.add({
|
||||||
|
// title: "hello world",
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
// import { useCounterStore } from "~/stores/counter";
|
// import { useCounterStore } from "~/stores/counter";
|
||||||
// import { storeToRefs } from "pinia";
|
// import { storeToRefs } from "pinia";
|
||||||
|
|
||||||
|
|
|
@ -60,3 +60,6 @@
|
||||||
|
|
||||||
// responsive
|
// responsive
|
||||||
@import "responsive/responsive";
|
@import "responsive/responsive";
|
||||||
|
|
||||||
|
// @import "tailwindcss";
|
||||||
|
// @import "@nuxt/ui";
|
||||||
|
|
|
@ -59,3 +59,6 @@
|
||||||
|
|
||||||
// responsive
|
// responsive
|
||||||
@import "responsive/responsive";
|
@import "responsive/responsive";
|
||||||
|
|
||||||
|
// @import "tailwindcss";
|
||||||
|
// @import "@nuxt/ui";
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
@import "src/assets/common/scss/mixin";
|
// @import "src/assets/common/scss/mixin";
|
||||||
@import "src/assets/common/scss/placeholder";
|
// @import "src/assets/common/scss/placeholder";
|
||||||
|
@import "@/assets/common/scss/mixin";
|
||||||
|
@import "@/assets/common/scss/placeholder";
|
||||||
|
|
||||||
.admin-system,.task-system,.admin-panel{
|
.admin-system,.task-system,.admin-panel{
|
||||||
//@import "main";
|
//@import "main";
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
@import "src/assets/common/scss/mixin";
|
// @import "src/assets/common/scss/mixin";
|
||||||
@import "src/assets/common/scss/placeholder";
|
// @import "src/assets/common/scss/placeholder";
|
||||||
|
@import "@/assets/common/scss/mixin";
|
||||||
|
@import "@/assets/common/scss/placeholder";
|
||||||
|
|
||||||
.admin-panel {
|
.admin-panel {
|
||||||
.pages-content-container {
|
.pages-content-container {
|
||||||
|
|
|
@ -106,7 +106,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import authMixin from "~/mixins/authMixin";
|
import authMixin from "~/mixins/authMixin";
|
||||||
import { required, minLength } from "vuelidate/lib/validators";
|
import { required,minLength } from '@vuelidate/validators'
|
||||||
|
import useVuelidate from '@vuelidate/core'
|
||||||
|
|
||||||
|
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import authMixin from "~/mixins/authMixin";
|
import authMixin from "~/mixins/authMixin";
|
||||||
import { required, minLength } from "vuelidate/lib/validators";
|
|
||||||
|
import { required, minLength } from "@vuelidate/validators";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
import { useAuthStore } from "~/stores/authStore";
|
import { useAuthStore } from "~/stores/authStore";
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
|
@ -147,7 +148,11 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useAuthStore,["getMobile", "getFullName", "getResetPasswordState"]),
|
...mapState(useAuthStore, [
|
||||||
|
"getMobile",
|
||||||
|
"getFullName",
|
||||||
|
"getResetPasswordState",
|
||||||
|
]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetErrors() {
|
resetErrors() {
|
||||||
|
@ -187,7 +192,7 @@ export default {
|
||||||
|
|
||||||
const { $eventBus } = useNuxtApp();
|
const { $eventBus } = useNuxtApp();
|
||||||
$eventBus.emit(
|
$eventBus.emit(
|
||||||
'authenticated-by-modal',
|
"authenticated-by-modal",
|
||||||
this.$route.query["invite-id"]
|
this.$route.query["invite-id"]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import {
|
||||||
minLength,
|
minLength,
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "forget",
|
name: "forget",
|
||||||
|
|
|
@ -156,7 +156,7 @@ import {
|
||||||
minLength,
|
minLength,
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -116,7 +116,7 @@ import {
|
||||||
minLength,
|
minLength,
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
|
@ -207,7 +207,7 @@ import {
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
sameAs,
|
sameAs,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mounted(){
|
mounted(){
|
||||||
|
|
|
@ -93,7 +93,7 @@ import {
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
sameAs,
|
sameAs,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
validations: {
|
validations: {
|
||||||
|
|
|
@ -110,7 +110,7 @@ import {
|
||||||
required,
|
required,
|
||||||
minLength,
|
minLength,
|
||||||
sameAs,
|
sameAs,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
import { useAuthStore } from "~/stores/authStore";
|
import { useAuthStore } from "~/stores/authStore";
|
||||||
|
|
|
@ -34,12 +34,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import authMixin from "~/mixins/authMixin";
|
import authMixin from "~/mixins/authMixin";
|
||||||
import {
|
|
||||||
required,
|
import { required, minLength, maxLength, between } from "@vuelidate/validators";
|
||||||
minLength,
|
|
||||||
maxLength,
|
|
||||||
between,
|
|
||||||
} from "vuelidate/lib/validators";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "forget",
|
name: "forget",
|
||||||
|
|
|
@ -116,7 +116,7 @@ import {
|
||||||
minLength,
|
minLength,
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
|
@ -146,7 +146,7 @@ import {
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
sameAs,
|
sameAs,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
validations: {
|
validations: {
|
||||||
|
|
|
@ -107,7 +107,7 @@ import {
|
||||||
required,
|
required,
|
||||||
minLength,
|
minLength,
|
||||||
sameAs,
|
sameAs,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -44,7 +44,7 @@ import {
|
||||||
minLength,
|
minLength,
|
||||||
maxLength,
|
maxLength,
|
||||||
between,
|
between,
|
||||||
} from "vuelidate/lib/validators";
|
} from "@vuelidate/validators";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
validations: {
|
validations: {
|
||||||
|
|
|
@ -63,8 +63,8 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 mb-2 mb-sm-0 col-md mb-sm-2 mb-md-0">
|
<div class="col-sm-6 mb-2 mb-sm-0 col-md mb-sm-2 mb-md-0">
|
||||||
<div class="link-item-container">
|
<div class="link-item-container">
|
||||||
<a
|
<NuxtLink
|
||||||
:href="urlResolver('qq309202')"
|
:to="urlResolver('qq309202')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="btn link-item"
|
class="btn link-item"
|
||||||
>
|
>
|
||||||
|
@ -80,13 +80,13 @@
|
||||||
<div class="more-text-container">
|
<div class="more-text-container">
|
||||||
<span class="more-text"> مشاهده بیشتر </span>
|
<span class="more-text"> مشاهده بیشتر </span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 mb-2 mb-sm-0 col-md mb-sm-2 mb-md-0">
|
<div class="col-sm-6 mb-2 mb-sm-0 col-md mb-sm-2 mb-md-0">
|
||||||
<div class="link-item-container">
|
<div class="link-item-container">
|
||||||
<a
|
<NuxtLink
|
||||||
:href="urlResolver('qq308235')"
|
:to="urlResolver('qq308235')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="btn link-item"
|
class="btn link-item"
|
||||||
>
|
>
|
||||||
|
@ -100,13 +100,13 @@
|
||||||
<div class="more-text-container">
|
<div class="more-text-container">
|
||||||
<span class="more-text"> مشاهده بیشتر </span>
|
<span class="more-text"> مشاهده بیشتر </span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 mb-2 mb-sm-0 col-md">
|
<div class="col-sm-6 mb-2 mb-sm-0 col-md">
|
||||||
<div class="link-item-container">
|
<div class="link-item-container">
|
||||||
<a
|
<NuxtLink
|
||||||
:href="urlResolver('qq38162')"
|
:to="urlResolver('qq38162')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="btn link-item"
|
class="btn link-item"
|
||||||
>
|
>
|
||||||
|
@ -120,13 +120,13 @@
|
||||||
<div class="more-text-container">
|
<div class="more-text-container">
|
||||||
<span class="more-text"> مشاهده بیشتر </span>
|
<span class="more-text"> مشاهده بیشتر </span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 mb-2 mb-sm-0 col-md">
|
<div class="col-sm-6 mb-2 mb-sm-0 col-md">
|
||||||
<div class="link-item-container">
|
<div class="link-item-container">
|
||||||
<a
|
<NuxtLink
|
||||||
:href="urlResolver('qq233930')"
|
:to="urlResolver('qq233930')"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="btn link-item"
|
class="btn link-item"
|
||||||
>
|
>
|
||||||
|
@ -140,7 +140,7 @@
|
||||||
<div class="more-text-container">
|
<div class="more-text-container">
|
||||||
<span class="more-text"> مشاهده بیشتر </span>
|
<span class="more-text"> مشاهده بیشتر </span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -156,7 +156,8 @@ import searchApi from "~/apis/searchApi";
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
import { useStorage } from "@vueuse/core";
|
import { useStorage } from "@vueuse/core";
|
||||||
import {clearBodyClass} from "@manuals/utilities"
|
import { clearBodyClass } from "@manuals/utilities";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
@ -255,7 +256,9 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
urlResolver(_id) {
|
urlResolver(_id) {
|
||||||
return "";
|
const router = `search/qasection/${_id}/show`;
|
||||||
|
|
||||||
|
return router;
|
||||||
// const routeData = this.$router.resolve({
|
// const routeData = this.$router.resolve({
|
||||||
// path: "navigation",
|
// path: "navigation",
|
||||||
// params: {
|
// params: {
|
||||||
|
@ -272,7 +275,6 @@ export default {
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../../../assets/majles/scss/majles";
|
@import "../../../assets/majles/scss/majles";
|
||||||
|
|
||||||
.custom-class {
|
.custom-class {
|
||||||
.dropdown-toggle {
|
.dropdown-toggle {
|
||||||
color: rgba(0, 0, 0, 0.5) !important;
|
color: rgba(0, 0, 0, 0.5) !important;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
>{{ getLabel() }}:</label
|
>{{ getLabel() }}:</label
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<codemirror
|
<!-- <codemirror
|
||||||
:options="cmOptions"
|
:options="cmOptions"
|
||||||
class="markdown-preview"
|
class="markdown-preview"
|
||||||
v-model="textValue"
|
v-model="textValue"
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
:id="localFormElement.key"
|
:id="localFormElement.key"
|
||||||
:name="localFormElement.key"
|
:name="localFormElement.key"
|
||||||
ref="myCm"
|
ref="myCm"
|
||||||
></codemirror>
|
></codemirror> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -21,20 +21,20 @@
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
import formBuilderMixin from "@mixins/formBuilderMixin";
|
import formBuilderMixin from "@mixins/formBuilderMixin";
|
||||||
|
|
||||||
import { codemirror } from "vue-codemirror";
|
// import { codemirror } from "vue-codemirror";
|
||||||
import "vue-codemirror/node_modules/codemirror/lib/codemirror.css";
|
// import "vue-codemirror/node_modules/codemirror/lib/codemirror.css";
|
||||||
import "vue-codemirror/node_modules/codemirror/mode/markdown/markdown.js";
|
// import "vue-codemirror/node_modules/codemirror/mode/markdown/markdown.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/mode/javascript/javascript.js";
|
// import "vue-codemirror/node_modules/codemirror/mode/javascript/javascript.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/mode/css/css.js";
|
// import "vue-codemirror/node_modules/codemirror/mode/css/css.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/mode/vue/vue.js";
|
// import "vue-codemirror/node_modules/codemirror/mode/vue/vue.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/mode/htmlmixed/htmlmixed.js";
|
// import "vue-codemirror/node_modules/codemirror/mode/htmlmixed/htmlmixed.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/edit/closebrackets.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/edit/closebrackets.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/edit/matchbrackets.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/edit/matchbrackets.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/edit/closetag.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/edit/closetag.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/display/placeholder.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/display/placeholder.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/scroll/simplescrollbars.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/scroll/simplescrollbars.js";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/scroll/simplescrollbars.css";
|
// import "vue-codemirror/node_modules/codemirror/addon/scroll/simplescrollbars.css";
|
||||||
import "vue-codemirror/node_modules/codemirror/addon/selection/active-line.js";
|
// import "vue-codemirror/node_modules/codemirror/addon/selection/active-line.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [formBuilderMixin],
|
mixins: [formBuilderMixin],
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="row form-group" :key="$attrs.key">
|
<div class="row form-group" :key="$attrs.key">
|
||||||
<label :for="localFormElement?.key" class="col-md-3">{{
|
<label :for="localFormElement?.key" class="col-md-3"
|
||||||
localFormElement?.label
|
>{{ localFormElement?.label }}:</label
|
||||||
}}:</label>
|
>
|
||||||
|
|
||||||
<div v-if="isInitial" class="dropbox">
|
<div v-if="isInitial" class="dropbox">
|
||||||
<input
|
<input
|
||||||
|
@ -57,8 +57,8 @@ const STATUS_INITIAL = 0,
|
||||||
STATUS_SUCCESS = 2,
|
STATUS_SUCCESS = 2,
|
||||||
STATUS_FAILED = 3;
|
STATUS_FAILED = 3;
|
||||||
|
|
||||||
import { upload } from "@services/fileUploadService";
|
// import { upload } from "@services/fileUploadService.js";
|
||||||
import { wait } from "@utilities/utilities.js";
|
import { wait } from "~/manuals/utilities.js";
|
||||||
|
|
||||||
import formBuilderMixin from "@mixins/formBuilderMixin";
|
import formBuilderMixin from "@mixins/formBuilderMixin";
|
||||||
export default {
|
export default {
|
||||||
|
@ -107,16 +107,16 @@ export default {
|
||||||
// upload data to the server
|
// upload data to the server
|
||||||
this.currentStatus = STATUS_SAVING;
|
this.currentStatus = STATUS_SAVING;
|
||||||
|
|
||||||
upload(formData)
|
// upload(formData)
|
||||||
.then(wait(1500)) // DEV ONLY: wait for 1.5s
|
// .then(wait(1500)) // DEV ONLY: wait for 1.5s
|
||||||
.then((x) => {
|
// .then((x) => {
|
||||||
this.uploadedFiles = [].concat(x);
|
// this.uploadedFiles = [].concat(x);
|
||||||
this.currentStatus = STATUS_SUCCESS;
|
// this.currentStatus = STATUS_SUCCESS;
|
||||||
})
|
// })
|
||||||
.catch((err) => {
|
// .catch((err) => {
|
||||||
this.uploadError = err.response;
|
// this.uploadError = err.response;
|
||||||
this.currentStatus = STATUS_FAILED;
|
// this.currentStatus = STATUS_FAILED;
|
||||||
});
|
// });
|
||||||
},
|
},
|
||||||
reset() {
|
reset() {
|
||||||
// reset form to initial state
|
// reset form to initial state
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default {
|
||||||
// datePicker: VuePersianDatetimePicker,
|
// datePicker: VuePersianDatetimePicker,
|
||||||
datePicker: () =>
|
datePicker: () =>
|
||||||
import(
|
import(
|
||||||
"vue-persian-datetime-picker"
|
"vue3-persian-datetime-picker"
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,13 +30,15 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import formBuilderMixin from "@mixins/formBuilderMixin";
|
import formBuilderMixin from "@mixins/formBuilderMixin";
|
||||||
import HttpService from "@services/httpService";
|
// import HttpService from "@services/httpService";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// props:["listOptions"],
|
// props:["listOptions"],
|
||||||
|
|
||||||
mixins: [formBuilderMixin],
|
mixins: [formBuilderMixin],
|
||||||
|
created() {
|
||||||
|
this.httpService = useNuxtApp()["$http"];
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.setOptions();
|
this.setOptions();
|
||||||
|
@ -45,7 +47,7 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
httpService: undefined,
|
httpService: {},
|
||||||
optionRendering: false,
|
optionRendering: false,
|
||||||
listOptions: [],
|
listOptions: [],
|
||||||
};
|
};
|
||||||
|
@ -173,7 +175,7 @@ export default {
|
||||||
if (this.optionRendering) return;
|
if (this.optionRendering) return;
|
||||||
|
|
||||||
let vm = this;
|
let vm = this;
|
||||||
this.httpService = new HttpService();
|
// this.httpService = new HttpService();
|
||||||
|
|
||||||
this.optionRendering = true;
|
this.optionRendering = true;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
|
<client-only>
|
||||||
<aside
|
<aside
|
||||||
class="nav-sidebar"
|
class="nav-sidebar"
|
||||||
:class="[
|
:class="[
|
||||||
|
@ -68,7 +69,10 @@
|
||||||
</span>
|
</span>
|
||||||
</NuxtLink>
|
</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">
|
<li class="fly-out-top-item active gl-link">
|
||||||
<span class="fly-out-top-item-container">
|
<span class="fly-out-top-item-container">
|
||||||
<strong class="fly-out-top-item-name">
|
<strong class="fly-out-top-item-name">
|
||||||
|
@ -207,8 +211,14 @@
|
||||||
@mouseleave="emitCustomEvent($event, 'out')"
|
@mouseleave="emitCustomEvent($event, 'out')"
|
||||||
>
|
>
|
||||||
<a class="has-sub-items gl-link">
|
<a class="has-sub-items gl-link">
|
||||||
<svg v-if="isGuest && showRegister" class="icon icon-personal">
|
<svg
|
||||||
<use class="icon-personal" xlink:href="#icon-personal"></use>
|
v-if="isGuest && showRegister"
|
||||||
|
class="icon icon-personal"
|
||||||
|
>
|
||||||
|
<use
|
||||||
|
class="icon-personal"
|
||||||
|
xlink:href="#icon-personal"
|
||||||
|
></use>
|
||||||
</svg>
|
</svg>
|
||||||
<img
|
<img
|
||||||
v-else
|
v-else
|
||||||
|
@ -338,6 +348,7 @@
|
||||||
|
|
||||||
<SvgIconComponent></SvgIconComponent>
|
<SvgIconComponent></SvgIconComponent>
|
||||||
</aside>
|
</aside>
|
||||||
|
</client-only>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
|
|
80
components/other/ImageCropper.vue
Normal 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>
|
|
@ -86,13 +86,13 @@ import repoApi from "~/apis/repoApi";
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
||||||
import SelectComponentDefault from "~/components/SelectComponentDefault.vue";
|
import SelectComponentDefault from "~/components/other/SelectComponentDefault.vue";
|
||||||
import SelectComponent from "~/components/SelectComponent.vue";
|
import SelectComponent from "~/components/other/SelectComponent.vue";
|
||||||
import InputComponent from "~/components/InputComponent.vue";
|
import InputComponent from "~/components/other/InputComponent.vue";
|
||||||
import LabelComponent from "~/components/LabelComponent.vue";
|
import LabelComponent from "~/components/other/LabelComponent.vue";
|
||||||
import tagsComponent from "~/components/tagsComponent.vue";
|
import tagsComponent from "~/components/other/tagsComponent.vue";
|
||||||
import DateComponent from "~/components/DateComponent.vue";
|
import DateComponent from "~/components/other/DateComponent.vue";
|
||||||
import TextareaComponent from "~/components/TextareaComponent.vue";
|
import TextareaComponent from "~/components/other/TextareaComponent.vue";
|
||||||
/**
|
/**
|
||||||
* @vue-data {Object} [listUpdatedText = {}] - متنهای بهروزشده در لیست.
|
* @vue-data {Object} [listUpdatedText = {}] - متنهای بهروزشده در لیست.
|
||||||
* @vue-data {undefined} [httpService = undefined] - سرویس HTTP برای درخواستها.
|
* @vue-data {undefined} [httpService = undefined] - سرویس HTTP برای درخواستها.
|
||||||
|
|
26
composables/useHadithaSearchComposable.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// composables/useHadithaSearchComposable.js
|
||||||
|
import { useStorage } from "@vueuse/core";
|
||||||
|
|
||||||
|
export const useHadithaSearchComposable = <T>(url: string, options = {}) => {
|
||||||
|
// Get the authentication token (e.g., from a cookie or local storage)
|
||||||
|
// const token = useCookie('auth-token') // Assuming you store the token in a cookie
|
||||||
|
let token = useStorage("id_token", "GuestAccess");
|
||||||
|
const config = useRuntimeConfig();
|
||||||
|
console.info(config);
|
||||||
|
|
||||||
|
const baseURL =
|
||||||
|
config.public.NUXT_PUBLIC_BASE_URL + config.public.NUXT_PUBLIC_API_NAME;
|
||||||
|
|
||||||
|
// Add headers to the request
|
||||||
|
const headers = {
|
||||||
|
Authorization: token.value,
|
||||||
|
...options.headers, // Merge with any existing headers
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use useFetch with the headers
|
||||||
|
return useFetch<T>(url, {
|
||||||
|
...options,
|
||||||
|
baseURL,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,44 +1,44 @@
|
||||||
import { useStorage } from "@vueuse/core";
|
// import { useStorage } from "@vueuse/core";
|
||||||
|
|
||||||
import { ref } from "vue";
|
// import { ref } from "vue";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
// import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
||||||
export function useMyComposable() {
|
// export function useMyComposable() {
|
||||||
const count = ref(0);
|
// const count = ref(0);
|
||||||
|
|
||||||
const increment = () => {
|
// const increment = () => {
|
||||||
count.value++;
|
// count.value++;
|
||||||
};
|
// };
|
||||||
|
|
||||||
const decrement = () => {
|
// const decrement = () => {
|
||||||
count.value--;
|
// count.value--;
|
||||||
};
|
// };
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
count,
|
// count,
|
||||||
increment,
|
// increment,
|
||||||
decrement,
|
// decrement,
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function useGetSchema() {
|
// export function useGetSchema() {
|
||||||
const commonStore = useCommonStore();
|
// const commonStore = useCommonStore();
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
return useAsyncData("shema", () =>
|
// return useAsyncData("shema", () =>
|
||||||
$fetch("/api/ali", {
|
// $fetch("/api/ali", {
|
||||||
headers: {
|
// headers: {
|
||||||
headers: { Authorization: useStorage("id_token") },
|
// headers: { Authorization: useStorage("id_token") },
|
||||||
},
|
// },
|
||||||
method: "post",
|
// method: "post",
|
||||||
body: {
|
// body: {
|
||||||
organ: commonStore.organNameGetter,
|
// organ: commonStore.organNameGetter,
|
||||||
system: "search",
|
// system: "search",
|
||||||
build_state: buildState(),
|
// build_state: buildState(),
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
);
|
// );
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
console.info(err);
|
// console.info(err);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -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>
|
|
|
@ -1,8 +1,9 @@
|
||||||
<!-- layouts/default.vue -->
|
<!-- layouts/default.vue -->
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<header v-if="buildName() != 'majles'">
|
|
||||||
<!-- //////////////////// begin navbar //////////////////// -->
|
<!-- //////////////////// begin navbar //////////////////// -->
|
||||||
|
<template v-if="$attrs.showNavbar">
|
||||||
|
<header v-if="buildName() != 'majles'">
|
||||||
<nav
|
<nav
|
||||||
class="navbar navbar-expand-md navbar-light bg-light"
|
class="navbar navbar-expand-md navbar-light bg-light"
|
||||||
:class="{ expanded: !isSidebarCollapsed }"
|
:class="{ expanded: !isSidebarCollapsed }"
|
||||||
|
@ -28,8 +29,8 @@
|
||||||
<button
|
<button
|
||||||
class="navbar-toggler"
|
class="navbar-toggler"
|
||||||
type="button"
|
type="button"
|
||||||
data-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-target="#navbarSupportedContent"
|
data-bs-target="#navbarSupportedContent"
|
||||||
aria-controls="navbarSupportedContent"
|
aria-controls="navbarSupportedContent"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-label="Toggle navigation"
|
aria-label="Toggle navigation"
|
||||||
|
@ -50,10 +51,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn p-0 mr-auto"
|
class="btn p-0 me-auto"
|
||||||
type="button"
|
type="button"
|
||||||
data-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-target="#navbarSupportedContent"
|
data-bs-target="#navbarSupportedContent"
|
||||||
aria-controls="navbarSupportedContent"
|
aria-controls="navbarSupportedContent"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-label="Toggle navigation"
|
aria-label="Toggle navigation"
|
||||||
|
@ -63,7 +64,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<ul class="navbar-nav ml-auto mr-md-5">
|
<ul class="navbar-nav ms-auto me-md-5">
|
||||||
<!-- <li class="nav-item active">
|
<!-- <li class="nav-item active">
|
||||||
<a class="nav-link" href="#"
|
<a class="nav-link" href="#"
|
||||||
>پیشخوان <span class="sr-only">(current)</span></a
|
>پیشخوان <span class="sr-only">(current)</span></a
|
||||||
|
@ -77,7 +78,7 @@
|
||||||
class="nav-link dropdown-toggle"
|
class="nav-link dropdown-toggle"
|
||||||
id="navbarDropdown"
|
id="navbarDropdown"
|
||||||
role="button"
|
role="button"
|
||||||
data-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
|
@ -93,7 +94,7 @@
|
||||||
href="#"
|
href="#"
|
||||||
id="navbarDropdown"
|
id="navbarDropdown"
|
||||||
role="button"
|
role="button"
|
||||||
data-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
|
@ -128,7 +129,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="navbar-nav ml-md-3 mr-auto">
|
<ul class="navbar-nav ms-md-3 me-auto">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<notification></notification>
|
<notification></notification>
|
||||||
</li>
|
</li>
|
||||||
|
@ -145,23 +146,32 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<!-- //////////////////// end navbar //////////////////// -->
|
|
||||||
</header>
|
</header>
|
||||||
|
</template>
|
||||||
|
<!-- //////////////////// end navbar //////////////////// -->
|
||||||
|
|
||||||
<!-- <the-sidebar :showUserAvatar="true" :menu="menu"></the-sidebar> -->
|
<!-- <the-sidebar :showUserAvatar="true" :menu="menu"></the-sidebar> -->
|
||||||
<the-sidebar
|
<the-sidebar
|
||||||
:showUserAvatar="true"
|
:showUserAvatar="true"
|
||||||
:menu="$attrs.menu"
|
:menu="$attrs.menu"
|
||||||
|
@statusPag="statusPag"
|
||||||
></the-sidebar>
|
></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 list-page"> -->
|
||||||
<!-- <div class="pages-content align-items-stretch p-0"> -->
|
<!-- <div class="pages-content align-items-stretch p-0"> -->
|
||||||
<!-- <div class="flex-grow-1"> -->
|
<!-- <div class="flex-grow-1"> -->
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</main>
|
</main>
|
||||||
|
</client-only>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -169,7 +179,7 @@
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "~/stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
||||||
import {clearBodyClass} from "@manuals/utilities"
|
import { clearBodyClass } from "@manuals/utilities";
|
||||||
export default {
|
export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
// this.setBodyClass("default-dashboard");
|
// this.setBodyClass("default-dashboard");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// middleware/redirect.js
|
// middleware/redirect.js
|
||||||
export default defineNuxtRouteMiddleware((to, from) => {
|
export default defineNuxtRouteMiddleware((to, from) => {
|
||||||
if (buildName() == "hadith" && to.path == '/') return navigateTo({ name: "hadith" });
|
if (buildName() == "haditha" && to.path == '/') return navigateTo({ name: "haditha" });
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,8 @@ export default {
|
||||||
]),
|
]),
|
||||||
// callFrom : page | modal
|
// callFrom : page | modal
|
||||||
async authBase(methodName, callFrom = "page") {
|
async authBase(methodName, callFrom = "page") {
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
// this.$v.$touch();
|
// this.$v.$touch();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -51,16 +53,19 @@ export default {
|
||||||
|
|
||||||
this[methodName]()
|
this[methodName]()
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// mySwalToast({
|
toast.add({
|
||||||
// title: res.message,
|
title: res.message,
|
||||||
// icon: "success",
|
icon: "success",
|
||||||
// timer: 2000,
|
timer: 2000,
|
||||||
// });
|
});
|
||||||
|
|
||||||
if (callFrom == "modal") {
|
if (callFrom == "modal") {
|
||||||
// fired event cached in the Group.vue and ChatList.vue
|
// fired event cached in the Group.vue and ChatList.vue
|
||||||
const { $eventBus } = useNuxtApp();
|
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.
|
// if redirected from chat system to relogin.
|
||||||
else {
|
else {
|
||||||
|
@ -81,10 +86,12 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
mySwalToast({
|
toast.add({
|
||||||
title: err.message,
|
title: err.message,
|
||||||
icon: "error",
|
icon: "error",
|
||||||
|
timer: 2000,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.resetCaptcha();
|
this.resetCaptcha();
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|
358
mixins/formBuilderMixin.js
Normal file
|
@ -0,0 +1,358 @@
|
||||||
|
export default {
|
||||||
|
props: ["formElement", "keyValue"],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options: {
|
||||||
|
controls: [
|
||||||
|
// "play-large", // The large play button in the center
|
||||||
|
//'restart', // Restart playback
|
||||||
|
// "rewind", // Rewind by the seek time (default 10 seconds)
|
||||||
|
"play", // Play/pause playback
|
||||||
|
// "fast-forward", // Fast forward by the seek time (default 10 seconds)
|
||||||
|
"progress", // The progress bar and scrubber for playback and buffering
|
||||||
|
"current-time", // The current time of playback
|
||||||
|
// "duration", // The full duration of the media
|
||||||
|
"mute", // Toggle mute
|
||||||
|
"volume", // Volume control
|
||||||
|
// "captions", // Toggle captions
|
||||||
|
"settings", // Settings menu
|
||||||
|
// "pip", // Picture-in-picture (currently Safari only)
|
||||||
|
// "airplay", // Airplay (currently Safari only)
|
||||||
|
"download", // Show a download button with a link to either the current source or a custom URL you specify in your options
|
||||||
|
// "fullscreen", // Toggle fullscreen
|
||||||
|
],
|
||||||
|
speed: { selected: 1, options: [0.75, 1, 1.5, 2] },
|
||||||
|
},
|
||||||
|
hasError: false,
|
||||||
|
localFormElement: {},
|
||||||
|
textValue: "",
|
||||||
|
emit_disable: false,
|
||||||
|
textValuePrev: "",
|
||||||
|
textDate: [],
|
||||||
|
objectValue: {}, // for select component {text, value}
|
||||||
|
isUpdateitem: false,
|
||||||
|
renderKey:1,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
beforeMount() {
|
||||||
|
this.$root.$on("catch-form-builder-event", this.listenEventBus);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.$root.$off("catch-form-builder-event", this.listenEventBus);
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
// this.textValue = this.value;
|
||||||
|
// this.textItem = this.value
|
||||||
|
|
||||||
|
this.disableEmitTemprory(2000);
|
||||||
|
|
||||||
|
this.localFormElement = this.formElement;
|
||||||
|
this.textValuePrev = this.localFormElement.value;
|
||||||
|
this.initTextValue();
|
||||||
|
this.textValuePrev = this.textValue;
|
||||||
|
// this.date = this.textValue; // for DateCompnent
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
formElement: {
|
||||||
|
handler(newValue) {
|
||||||
|
this.localFormElement = newValue;
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
nested: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
textValue(newVal) {
|
||||||
|
// console.log(this.localFormElement.key, newVal)
|
||||||
|
if (this.textValuePrev == newVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let [emitValue, emitValueObject] = this.parseValueToEmit(newVal)
|
||||||
|
|
||||||
|
// if (!this.emit_disable)
|
||||||
|
// console.log(this.localFormElement.key, newVal, emitValue, this.localFormElement.value)
|
||||||
|
if(this.localFormElement.value != emitValue)
|
||||||
|
this.$emit("take-value", emitValue);
|
||||||
|
|
||||||
|
if (emitValueObject) this.parseAffectedToEventBus(emitValueObject); // for select only
|
||||||
|
else this.parseAffectedToEventBus(emitValue);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
incrementRenderKey(){
|
||||||
|
this.renderKey = this.renderKey +1
|
||||||
|
this.$forceUpdate();
|
||||||
|
},
|
||||||
|
|
||||||
|
parseValueToEmit(newVal){
|
||||||
|
let emitValue = newVal;
|
||||||
|
let emitValueObject = undefined;
|
||||||
|
|
||||||
|
if (this.localFormElement?.type == "date") {
|
||||||
|
// console.info(newVal);
|
||||||
|
emitValue = newVal;
|
||||||
|
try {
|
||||||
|
if (this.localFormElement?.savetype == "timestamp") {
|
||||||
|
let dtStr = newVal;
|
||||||
|
// const dtStr = "2012/02/26";
|
||||||
|
const [y, m, d] = dtStr.split(/-|\//);
|
||||||
|
const date = new Date(y, m - 1, d);
|
||||||
|
// emitValue = date.toISOString();
|
||||||
|
emitValue = date.getTime()();
|
||||||
|
}
|
||||||
|
// if( this.localFormElement?.subtype == 'time' )
|
||||||
|
// return "HH:mm"
|
||||||
|
} catch {
|
||||||
|
emitValue = newVal;
|
||||||
|
}
|
||||||
|
// console.info(emitValue);
|
||||||
|
}
|
||||||
|
// input , textarea if multi items
|
||||||
|
else if (this.localFormElement?.isarray) {
|
||||||
|
let delim = this.localFormElement?.delimiter
|
||||||
|
? this.localFormElement.delimiter
|
||||||
|
: "-";
|
||||||
|
|
||||||
|
emitValue = [];
|
||||||
|
newVal
|
||||||
|
.split(delim)
|
||||||
|
.filter((el) => el.trim())
|
||||||
|
.forEach((el) => {
|
||||||
|
emitValue.push(el.trim());
|
||||||
|
});
|
||||||
|
// console.log(emitValue)
|
||||||
|
} else if (this.localFormElement.type == "select" && this.listOptions) {
|
||||||
|
// if(this.localFormElement.key == 'city'){
|
||||||
|
// }
|
||||||
|
emitValue = newVal;
|
||||||
|
//برای ذدخیره در بک کدام مقدار را بفرستد
|
||||||
|
if (this.localFormElement.value_save) {
|
||||||
|
emitValueObject = this.listOptions.find(
|
||||||
|
(item) => item.value == newVal
|
||||||
|
);
|
||||||
|
|
||||||
|
if (emitValueObject && this.localFormElement.value_save == "title") {
|
||||||
|
emitValue = emitValueObject.title ?? emitValueObject.value;
|
||||||
|
} else if (
|
||||||
|
emitValueObject &&
|
||||||
|
this.localFormElement.value_save == "object"
|
||||||
|
) {
|
||||||
|
emitValue = {
|
||||||
|
id: emitValueObject.value,
|
||||||
|
title: emitValueObject.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.localFormElement?.type == "number"){
|
||||||
|
if(this.localFormElement?.step != 1){
|
||||||
|
emitValue = parseFloat(newVal)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emitValue = parseInt(newVal)
|
||||||
|
}
|
||||||
|
else emitValue = newVal;
|
||||||
|
|
||||||
|
return [emitValue, emitValueObject]
|
||||||
|
|
||||||
|
},
|
||||||
|
listenEventBus({ value, affectedTo }) {
|
||||||
|
// console.log(affectedTo.key, this.localFormElement.key);
|
||||||
|
if (affectedTo.key === this.localFormElement.key) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// console.log(this.localFormElement.key, affectedTo, value);
|
||||||
|
// console.log(this[affectedTo.action])
|
||||||
|
this[affectedTo.action](value);
|
||||||
|
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseAffectedToEventBus(newValue) {
|
||||||
|
if (!this.localFormElement["affected-to"]) return;
|
||||||
|
|
||||||
|
// console.log("parseAffectedToEvent", newValue);
|
||||||
|
// console.log(newValue);
|
||||||
|
|
||||||
|
let affectedTo = this.localFormElement["affected-to"];
|
||||||
|
// console.log(affectedTo);
|
||||||
|
|
||||||
|
affectedTo.forEach((item_affectedTo) => {
|
||||||
|
let value = newValue;
|
||||||
|
if (
|
||||||
|
typeof newValue == "object" &&
|
||||||
|
item_affectedTo?.param &&
|
||||||
|
newValue[item_affectedTo?.param]
|
||||||
|
)
|
||||||
|
value = newValue[item_affectedTo?.param];
|
||||||
|
|
||||||
|
if (item_affectedTo?.emit) {
|
||||||
|
this.$emit( "action-affected-item", { action:item_affectedTo.emit, key: item_affectedTo.key, value});
|
||||||
|
// console.log("action-affected-item", { action:item_affectedTo.emit, key: item_affectedTo.key, value})
|
||||||
|
} else if (item_affectedTo?.action) {
|
||||||
|
this.$root.$emit("catch-form-builder-event", {
|
||||||
|
value: value,
|
||||||
|
affectedTo: item_affectedTo,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
disableEmitTemprory(timeout = 1000) {
|
||||||
|
this.emit_disable = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.emit_disable = false;
|
||||||
|
}, timeout);
|
||||||
|
},
|
||||||
|
|
||||||
|
clearErrors() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
getLabel() {
|
||||||
|
let label = this.localFormElement.label;
|
||||||
|
if (this.localFormElement?.required == "1") label = "*" + label;
|
||||||
|
return label;
|
||||||
|
},
|
||||||
|
validate(ev) {
|
||||||
|
const value = ev.target.value;
|
||||||
|
if (this.localFormElement.validate) {
|
||||||
|
// چک کردن برای وجود الگو
|
||||||
|
if (value) {
|
||||||
|
let pattern = this.localFormElement.validate;
|
||||||
|
// اگر الگوی ورودی معتبر باشد، تنظیم میکنیم که مقدار مطابقت دارد یا خیر
|
||||||
|
this.hasError = new RegExp(pattern).test(value);
|
||||||
|
} else {
|
||||||
|
// اگر مقدار ورودی خالی باشد، خطا بر اساس الزامی بودن فیلد تعیین میشود
|
||||||
|
this.hasError = this.localFormElement?.required ? true : false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// اگر الگوی validate وجود نداشته باشد، کاری انجام نمیدهیم
|
||||||
|
this.hasError = false;
|
||||||
|
}
|
||||||
|
// اعلان خطا به والد (component اصلی)
|
||||||
|
this.$emit("take-value-validate", this.hasError);
|
||||||
|
},
|
||||||
|
|
||||||
|
initTextValue(newValue=undefined) {
|
||||||
|
// console.log('initTextValue', this.localFormElement.key, newValue)
|
||||||
|
|
||||||
|
let value = "";
|
||||||
|
if(newValue)
|
||||||
|
value = newValue
|
||||||
|
else if(this.localFormElement.value)
|
||||||
|
value = this.localFormElement.value;
|
||||||
|
else if(this.localFormElement.value_defualt)
|
||||||
|
value = this.localFormElement.value_defualt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// در همه حالت نباید این باشد اگر لازم شد باید پیش فرض تنظیم شود
|
||||||
|
// ذخیره هم نمیشود ...!!!
|
||||||
|
// if (!value && this.localFormElement.type == "select") {
|
||||||
|
// value = this.listOptions.length > 0 ? this.listOptions[0].value : "";
|
||||||
|
// }
|
||||||
|
// console.log(this.localFormElement.key, value)
|
||||||
|
|
||||||
|
var mValue = value ?? "";
|
||||||
|
|
||||||
|
if (this.localFormElement?.type == "date") {
|
||||||
|
// console.info("setTextValue", mValue);
|
||||||
|
try {
|
||||||
|
var date = "";
|
||||||
|
if (mValue != "") {
|
||||||
|
if (this.localFormElement?.savetype == "timestamp") {
|
||||||
|
let timeWithMiliSeconds = mValue;
|
||||||
|
|
||||||
|
if ( this.isUnixTimestamp(mValue) && mValue.toString().length <= 11) {
|
||||||
|
timeWithMiliSeconds = mValue * 1000;
|
||||||
|
}
|
||||||
|
date = this.$moment(new Date(timeWithMiliSeconds)).format(
|
||||||
|
"YYYY-MM-DD HH:mm"
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
this.localFormElement?.savetype == "datetime" ||
|
||||||
|
this.localFormElement?.savetype == "date"
|
||||||
|
) {
|
||||||
|
date = this.$moment(new Date(mValue)).format("YYYY-MM-DD HH:mm");
|
||||||
|
} else date = mValue;
|
||||||
|
}
|
||||||
|
this.textDate = date;
|
||||||
|
mValue = date
|
||||||
|
} catch {
|
||||||
|
this.textDate = mValue;
|
||||||
|
}
|
||||||
|
} else if (this.localFormElement?.isarray) {
|
||||||
|
if (value && Array.isArray(value)) {
|
||||||
|
let delim = this.localFormElement?.delimiter
|
||||||
|
? this.localFormElement.delimiter
|
||||||
|
: "-";
|
||||||
|
mValue = value.join(delim);
|
||||||
|
} else mValue = "";
|
||||||
|
} else if (this.localFormElement.type == "select") {
|
||||||
|
if (this.localFormElement?.value_save == "title" && this.listOptions) {
|
||||||
|
// console.log('value_defualt', this.localFormElement.value_defualt)
|
||||||
|
let finded = this.listOptions.find((item) => {
|
||||||
|
if (item.title == value) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (finded) {
|
||||||
|
mValue = finded.value;
|
||||||
|
// console.log('finded', finded)
|
||||||
|
} else {
|
||||||
|
mValue =
|
||||||
|
this.listOptions.length > 0 ? this.listOptions[0].value : "";
|
||||||
|
}
|
||||||
|
} else if (this.localFormElement?.value_save == "object") {
|
||||||
|
mValue = value.value;
|
||||||
|
} else mValue = value ?? "";
|
||||||
|
} else {
|
||||||
|
mValue = value ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//نیازی به ارسال تغییر در واچ نیست
|
||||||
|
if(this.localFormElement.value == value )
|
||||||
|
this.textValuePrev == value
|
||||||
|
|
||||||
|
this.textValue = mValue
|
||||||
|
|
||||||
|
// console.log(' this.textValue', this.localFormElement.key, this.textValue)
|
||||||
|
},
|
||||||
|
isUnixTimestamp(value) {
|
||||||
|
// Check if the value is a number
|
||||||
|
if (typeof value !== "number" && !/^\d+$/.test(value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Convert to number if it's a string
|
||||||
|
value = parseInt(value);
|
||||||
|
// Unix timestamps are non-negative integers
|
||||||
|
return !isNaN(value) && value >= 0 && value % 1 === 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
sendTextValue() {
|
||||||
|
this.$emit("keydown", {
|
||||||
|
text: this.textValue,
|
||||||
|
key: this.keyValue,
|
||||||
|
isUpdate: this.isUpdateitem,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
////ااز هیچا فراخوانی نمیشه لذا کامنت کردم
|
||||||
|
//فقط برای select
|
||||||
|
// takeSelectValue($event, type) {
|
||||||
|
|
||||||
|
// this.objectValue = {
|
||||||
|
// value: $event.target.value,
|
||||||
|
// text: $event.target.selectedOptions[0].text,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// console.log('takeSelectValue',this.localFormElement.key , objectValue)
|
||||||
|
|
||||||
|
// this.$emit("take-select-object", {
|
||||||
|
// type: type,
|
||||||
|
// objectValue: this.objectValue,
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
import { mapState, mapActions } from "pinia";
|
import { mapState, mapActions } from "pinia";
|
||||||
import { useCommonStore } from "@stores/commonStore";
|
import { useCommonStore } from "~/stores/commonStore";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
created() {
|
created() {
|
||||||
|
|
164
nuxt.config.ts
|
@ -2,6 +2,11 @@
|
||||||
import fs from "fs-extra";
|
import fs from "fs-extra";
|
||||||
import path from "path";
|
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;
|
const envs = import.meta.env;
|
||||||
let sassEnvVariables = "";
|
let sassEnvVariables = "";
|
||||||
|
|
||||||
|
@ -13,20 +18,19 @@ for (let e in envs) {
|
||||||
|
|
||||||
// dynamically importing styles.
|
// dynamically importing styles.
|
||||||
const buildName = import.meta.env.VITE_BUILD_NAME;
|
const buildName = import.meta.env.VITE_BUILD_NAME;
|
||||||
let mainStyle = `~/assets/common/scss/${buildName}-styles.scss`;
|
|
||||||
|
|
||||||
if (buildName == "hadith")
|
|
||||||
mainStyle = `~/systems/${buildName}_ui/assets/${buildName}/scss/${buildName}.css`;
|
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
hooks: {
|
hooks: {
|
||||||
"build:before": () => {
|
"build:before": () => {
|
||||||
if (buildName == "hadith") {
|
if (buildName == "haditha") {
|
||||||
const sourceDir = path.resolve(
|
const sourceDir = path.resolve(
|
||||||
__dirname,
|
__dirname,
|
||||||
`systems/${buildName}_ui/assets/${buildName}/images`
|
`systems/${buildName.substring(
|
||||||
|
0,
|
||||||
|
buildName.length - 1
|
||||||
|
)}_ui/assets/${buildName}/images`
|
||||||
); // Source folder (e.g., assets/images)
|
); // Source folder (e.g., assets/images)
|
||||||
const targetDir = path.resolve(__dirname, "public/img"); // Target folder (e.g., public/images)
|
const targetDir = path.resolve(__dirname, `public/img/${buildName}`); // Target folder (e.g., public/images)
|
||||||
|
|
||||||
// Ensure the target directory exists
|
// Ensure the target directory exists
|
||||||
fs.ensureDirSync(targetDir);
|
fs.ensureDirSync(targetDir);
|
||||||
|
@ -40,96 +44,15 @@ export default defineNuxtConfig({
|
||||||
|
|
||||||
"pages:extend"(pages) {
|
"pages:extend"(pages) {
|
||||||
// Add custom routes
|
// Add custom routes
|
||||||
pages.push(
|
pages.push(...search, ...research, ...haditha, ...chat);
|
||||||
{
|
|
||||||
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: hadith routes ---------------------
|
|
||||||
{
|
|
||||||
name: "hadith",
|
|
||||||
path: "/hadith",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/index.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithSearch",
|
|
||||||
path: "/hadith/search",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/search/index.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithChatBot",
|
|
||||||
path: "/hadith/chat-bot",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/chat-bot.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithFavorites",
|
|
||||||
path: "/hadith/favorites",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/favorites/index.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithLibrary",
|
|
||||||
path: "/hadith/library",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/library/index.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithLibraryShow",
|
|
||||||
path: "/hadith/library/:id/:slug?",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/library/[id]/[slug]/index.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithAbout",
|
|
||||||
path: "/hadith/about-us",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/public-pages/about-us.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithContact",
|
|
||||||
path: "/hadith/contact-us",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/public-pages/ContactUs.vue",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "hadithRules",
|
|
||||||
path: "/hadith/rules",
|
|
||||||
file: "~/systems/hadith_ui/pages/hadith/public-pages/rules.vue",
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------- end: hadith routes ---------------------
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
nitro: {
|
nitro: {
|
||||||
compressPublicAssets: true,
|
compressPublicAssets: true,
|
||||||
|
prerender: {
|
||||||
|
routes: ["/haditha/about-us", "/haditha/contact"], // Pre-render these routes
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
colorMode: {
|
colorMode: {
|
||||||
|
@ -172,6 +95,17 @@ export default defineNuxtConfig({
|
||||||
"@nuxt/image",
|
"@nuxt/image",
|
||||||
// "@nuxtjs/supabase",
|
// "@nuxtjs/supabase",
|
||||||
],
|
],
|
||||||
|
icon: {
|
||||||
|
customCollections: [
|
||||||
|
{
|
||||||
|
prefix: "haditha",
|
||||||
|
dir: `./systems/${buildName.substring(
|
||||||
|
0,
|
||||||
|
buildName.length - 1
|
||||||
|
)}_ui/assets/${buildName}/font-icons`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
// ui: {
|
// ui: {
|
||||||
// prefix: 'Nuxt', //Use the prefix option to change the prefix of the components. Default: U
|
// prefix: 'Nuxt', //Use the prefix option to change the prefix of the components. Default: U
|
||||||
// fonts: false, // Use the fonts option to enable or disable the @nuxt/fonts module. Default: true
|
// fonts: false, // Use the fonts option to enable or disable the @nuxt/fonts module. Default: true
|
||||||
|
@ -185,29 +119,10 @@ export default defineNuxtConfig({
|
||||||
// debug: process.env.NODE_ENV === 'development',
|
// debug: process.env.NODE_ENV === 'development',
|
||||||
// mode: 'init'
|
// mode: 'init'
|
||||||
// },
|
// },
|
||||||
image: {
|
// image: {
|
||||||
inject: true,
|
// provider: "ipx",
|
||||||
quality: 80,
|
// quality: 100,
|
||||||
format: ["webp", "jpeg", "jpg", "png", "gif", "avif"],
|
// },
|
||||||
screens: {
|
|
||||||
xs: 320,
|
|
||||||
sm: 576,
|
|
||||||
md: 768,
|
|
||||||
lg: 1199,
|
|
||||||
xl: 1400,
|
|
||||||
xxl: 1600,
|
|
||||||
"2xl": 1920,
|
|
||||||
},
|
|
||||||
presets: {
|
|
||||||
avatar: {
|
|
||||||
modifiers: {
|
|
||||||
format: "jpg",
|
|
||||||
width: 25,
|
|
||||||
height: 24,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
i18n: {
|
i18n: {
|
||||||
vueI18n: "./i18n.config.ts", // if you are using custom path, default
|
vueI18n: "./i18n.config.ts", // if you are using custom path, default
|
||||||
},
|
},
|
||||||
|
@ -233,7 +148,7 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
css: [
|
css: [
|
||||||
mainStyle,
|
customStyleLoader(),
|
||||||
// "vue3-persian-datetime-picker/src/picker/assets/scss/style.scss",
|
// "vue3-persian-datetime-picker/src/picker/assets/scss/style.scss",
|
||||||
],
|
],
|
||||||
alias: {
|
alias: {
|
||||||
|
@ -253,7 +168,8 @@ export default defineNuxtConfig({
|
||||||
"@pages": "~/pages",
|
"@pages": "~/pages",
|
||||||
"@search": "~/systems/search_ui",
|
"@search": "~/systems/search_ui",
|
||||||
"@research": "~/systems/research_ui",
|
"@research": "~/systems/research_ui",
|
||||||
"@hadith": "~/systems/hadith_ui",
|
"@haditha": "~/systems/hadith_ui",
|
||||||
|
"@chat": "~/systems/chat_ui",
|
||||||
},
|
},
|
||||||
vite: {
|
vite: {
|
||||||
resolve: {},
|
resolve: {},
|
||||||
|
@ -275,6 +191,10 @@ export default defineNuxtConfig({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
build: {
|
||||||
|
analyze: true,
|
||||||
|
// transpile: ["echarts", "resize-detector", "echarts-wordcloud"],
|
||||||
|
},
|
||||||
// postcss: {
|
// postcss: {
|
||||||
// plugins: {
|
// plugins: {
|
||||||
// tailwindcss: {},
|
// tailwindcss: {},
|
||||||
|
@ -419,3 +339,13 @@ export default defineNuxtConfig({
|
||||||
// console.log(runtimeConfig.public.apiBase)
|
// console.log(runtimeConfig.public.apiBase)
|
||||||
|
|
||||||
// Resolve ~, ~~, @ and @@ aliases located within layers with respect to their layer source and root directories.
|
// 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;
|
||||||
|
}
|
||||||
|
|
207
package-lock.json
generated
|
@ -17,6 +17,8 @@
|
||||||
"@vueup/vue-quill": "^1.2.0",
|
"@vueup/vue-quill": "^1.2.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
|
"cropperjs": "^2.0.0",
|
||||||
"docx": "^9.1.1",
|
"docx": "^9.1.1",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"echarts-wordcloud": "^2.1.0",
|
"echarts-wordcloud": "^2.1.0",
|
||||||
|
@ -29,6 +31,8 @@
|
||||||
"i18next-vue": "^5.0.0",
|
"i18next-vue": "^5.0.0",
|
||||||
"jalali-moment": "^3.3.11",
|
"jalali-moment": "^3.3.11",
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
|
"lucide": "^0.477.0",
|
||||||
|
"lucide-vue-next": "^0.477.0",
|
||||||
"mammoth": "^1.8.0",
|
"mammoth": "^1.8.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"npm": "^11.1.0",
|
"npm": "^11.1.0",
|
||||||
|
@ -42,6 +46,7 @@
|
||||||
"vue-draggable-next": "^2.2.1",
|
"vue-draggable-next": "^2.2.1",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-i18n": "^10.0.1",
|
"vue-i18n": "^10.0.1",
|
||||||
|
"vue-image-upload-resize": "^2.3.0",
|
||||||
"vue-jalali-moment": "^1.0.0",
|
"vue-jalali-moment": "^1.0.0",
|
||||||
"vue-jstree": "^2.1.6",
|
"vue-jstree": "^2.1.6",
|
||||||
"vue-multiselect": "^3.0.0",
|
"vue-multiselect": "^3.0.0",
|
||||||
|
@ -53,9 +58,12 @@
|
||||||
"vue3-persian-datetime-picker": "^1.2.2",
|
"vue3-persian-datetime-picker": "^1.2.2",
|
||||||
"vue3-tree-vue": "^2.0.11",
|
"vue3-tree-vue": "^2.0.11",
|
||||||
"vuejs-paginate": "^2.1.0",
|
"vuejs-paginate": "^2.1.0",
|
||||||
"vuejs-paginate-next": "^1.0.2"
|
"vuejs-paginate-next": "^1.0.2",
|
||||||
|
"zod": "^3.24.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@iconify-json/lucide": "^1.2.28",
|
||||||
|
"@iconify-json/vscode-icons": "^1.2.16",
|
||||||
"@nuxt/test-utils": "^3.14.4",
|
"@nuxt/test-utils": "^3.14.4",
|
||||||
"@nuxtjs/i18n": "^9.0.0-rc.2",
|
"@nuxtjs/i18n": "^9.0.0-rc.2",
|
||||||
"@types/bootstrap": "^5.2.10",
|
"@types/bootstrap": "^5.2.10",
|
||||||
|
@ -667,7 +675,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.3.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.3.tgz",
|
||||||
"integrity": "sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==",
|
"integrity": "sha512-1dNIOmiM0z4BIBwxmxEfA1yoxh1MF/6KPBbh20a5vphGV0ictKlgQsbJs6D6SkR6iJpGbpwRsa6PFMNlg9T9pQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
|
@ -712,7 +719,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.3.tgz",
|
||||||
"integrity": "sha512-GSGfKxCo867P7EX1k2LoCrjuQFeqVgPGRRsSl4J4c0KMkD+k1y6WYvTQkzv0iZ8JhLJDujEvlnMchv4CZQLh3Q==",
|
"integrity": "sha512-GSGfKxCo867P7EX1k2LoCrjuQFeqVgPGRRsSl4J4c0KMkD+k1y6WYvTQkzv0iZ8JhLJDujEvlnMchv4CZQLh3Q==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
"@codemirror/view": "^6.35.0",
|
"@codemirror/view": "^6.35.0",
|
||||||
|
@ -724,7 +730,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.8.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.8.tgz",
|
||||||
"integrity": "sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig==",
|
"integrity": "sha512-PoWtZvo7c1XFeZWmmyaOp2G0XVbOnm+fJzvghqGAktBW3cufwJUWvSCcNG0ppXiBEM05mZu6RhMtXPv2hpllig==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/state": "^6.0.0",
|
"@codemirror/state": "^6.0.0",
|
||||||
"@codemirror/view": "^6.0.0",
|
"@codemirror/view": "^6.0.0",
|
||||||
|
@ -748,6 +753,126 @@
|
||||||
"w3c-keyname": "^2.2.4"
|
"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": {
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
"version": "0.24.2",
|
"version": "0.24.2",
|
||||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
|
||||||
|
@ -1463,6 +1588,26 @@
|
||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@iconify-json/lucide": {
|
||||||
|
"version": "1.2.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify-json/lucide/-/lucide-1.2.28.tgz",
|
||||||
|
"integrity": "sha512-SPeAoh1YKhALpNSto/FBspf3GZ0eAr3ka/OI7cJJ5HljLzycIITv0s4Rd2+sRVzFtD1I991mJJmYohQeOSZ+Og==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/types": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@iconify-json/vscode-icons": {
|
||||||
|
"version": "1.2.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iconify-json/vscode-icons/-/vscode-icons-1.2.16.tgz",
|
||||||
|
"integrity": "sha512-hstc2yVq2UJ6v6FrgjftzXRvphGZBsKxvSeXoFLP1Hgx89TPZKrGE5SV6vqsoeIlLYaQ7OZbXmAoVGroTfGmVQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@iconify/types": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@iconify/collections": {
|
"node_modules/@iconify/collections": {
|
||||||
"version": "1.0.516",
|
"version": "1.0.516",
|
||||||
"resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.516.tgz",
|
"resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.516.tgz",
|
||||||
|
@ -6302,6 +6447,12 @@
|
||||||
"integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
|
"integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
|
||||||
"license": "MIT"
|
"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": {
|
"node_modules/boolbase": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||||
|
@ -6845,7 +6996,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/commands": "^6.0.0",
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
@ -7112,8 +7262,7 @@
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/croner": {
|
"node_modules/croner": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
|
@ -7133,6 +7282,16 @@
|
||||||
"cronstrue": "bin/cli.js"
|
"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": {
|
"node_modules/cross-fetch": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
||||||
|
@ -10934,6 +11093,21 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/lucide": {
|
||||||
|
"version": "0.477.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lucide/-/lucide-0.477.0.tgz",
|
||||||
|
"integrity": "sha512-lEgt1ni9sKohbLsYWSnM3mKVRkvUrJ3Ijj01RAdM5F0iyvxkCcy3gPrb1G2ux6zE4y20ptcitfMa0OOFXI57gw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/lucide-vue-next": {
|
||||||
|
"version": "0.477.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-0.477.0.tgz",
|
||||||
|
"integrity": "sha512-C7azIKO7aJKf5MD7OIzV7NRDtnjXH3KSXfyJgGqRIMemuMzW/9esuMxDXIXDhBZcJgRtXMUN0FcJwOJZQ8SywA==",
|
||||||
|
"license": "ISC",
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": ">=3.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-regexp": {
|
"node_modules/magic-regexp": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/magic-regexp/-/magic-regexp-0.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/magic-regexp/-/magic-regexp-0.8.0.tgz",
|
||||||
|
@ -20410,6 +20584,16 @@
|
||||||
"vue": "^3.0.0"
|
"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": {
|
"node_modules/vue-jalali-moment": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/vue-jalali-moment/-/vue-jalali-moment-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-jalali-moment/-/vue-jalali-moment-1.0.0.tgz",
|
||||||
|
@ -21013,6 +21197,15 @@
|
||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/zod": {
|
||||||
|
"version": "3.24.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
|
||||||
|
"integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/zrender": {
|
"node_modules/zrender": {
|
||||||
"version": "5.6.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.6.0.tgz",
|
||||||
|
|
14
package.json
|
@ -11,8 +11,8 @@
|
||||||
"postinstall": "nuxt prepare",
|
"postinstall": "nuxt prepare",
|
||||||
"dev-tavasi": "env-cmd -f .env.tavasi nuxt dev --host --inspect",
|
"dev-tavasi": "env-cmd -f .env.tavasi nuxt dev --host --inspect",
|
||||||
"dev-monir": "env-cmd -f .env.monir nuxt dev --host --inspect",
|
"dev-monir": "env-cmd -f .env.monir nuxt dev --host --inspect",
|
||||||
"dev-hadith": "env-cmd -f .env.hadith nuxt dev --host --inspect",
|
"dev-haditha": "env-cmd -f .env.haditha nuxt dev --host --inspect",
|
||||||
"build-hadith": "env-cmd -f .env.hadith nuxt build"
|
"build-haditha": "env-cmd -f .env.haditha nuxt build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxt/image": "^1.8.1",
|
"@nuxt/image": "^1.8.1",
|
||||||
|
@ -25,6 +25,8 @@
|
||||||
"@vueup/vue-quill": "^1.2.0",
|
"@vueup/vue-quill": "^1.2.0",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
|
"codemirror": "^6.0.1",
|
||||||
|
"cropperjs": "^2.0.0",
|
||||||
"docx": "^9.1.1",
|
"docx": "^9.1.1",
|
||||||
"echarts": "^5.5.1",
|
"echarts": "^5.5.1",
|
||||||
"echarts-wordcloud": "^2.1.0",
|
"echarts-wordcloud": "^2.1.0",
|
||||||
|
@ -37,6 +39,8 @@
|
||||||
"i18next-vue": "^5.0.0",
|
"i18next-vue": "^5.0.0",
|
||||||
"jalali-moment": "^3.3.11",
|
"jalali-moment": "^3.3.11",
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
|
"lucide": "^0.477.0",
|
||||||
|
"lucide-vue-next": "^0.477.0",
|
||||||
"mammoth": "^1.8.0",
|
"mammoth": "^1.8.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"npm": "^11.1.0",
|
"npm": "^11.1.0",
|
||||||
|
@ -50,6 +54,7 @@
|
||||||
"vue-draggable-next": "^2.2.1",
|
"vue-draggable-next": "^2.2.1",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-i18n": "^10.0.1",
|
"vue-i18n": "^10.0.1",
|
||||||
|
"vue-image-upload-resize": "^2.3.0",
|
||||||
"vue-jalali-moment": "^1.0.0",
|
"vue-jalali-moment": "^1.0.0",
|
||||||
"vue-jstree": "^2.1.6",
|
"vue-jstree": "^2.1.6",
|
||||||
"vue-multiselect": "^3.0.0",
|
"vue-multiselect": "^3.0.0",
|
||||||
|
@ -61,9 +66,12 @@
|
||||||
"vue3-persian-datetime-picker": "^1.2.2",
|
"vue3-persian-datetime-picker": "^1.2.2",
|
||||||
"vue3-tree-vue": "^2.0.11",
|
"vue3-tree-vue": "^2.0.11",
|
||||||
"vuejs-paginate": "^2.1.0",
|
"vuejs-paginate": "^2.1.0",
|
||||||
"vuejs-paginate-next": "^1.0.2"
|
"vuejs-paginate-next": "^1.0.2",
|
||||||
|
"zod": "^3.24.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@iconify-json/lucide": "^1.2.28",
|
||||||
|
"@iconify-json/vscode-icons": "^1.2.16",
|
||||||
"@nuxt/test-utils": "^3.14.4",
|
"@nuxt/test-utils": "^3.14.4",
|
||||||
"@nuxtjs/i18n": "^9.0.0-rc.2",
|
"@nuxtjs/i18n": "^9.0.0-rc.2",
|
||||||
"@types/bootstrap": "^5.2.10",
|
"@types/bootstrap": "^5.2.10",
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<!-- majles dashbaord -->
|
<!-- majles dashbaord -->
|
||||||
<search-section v-if="buildName() == 'majles'"></search-section>
|
<search-section v-if="buildName() == 'majles'"></search-section>
|
||||||
<!-- monir dashboard -->
|
<!-- monir dashboard -->
|
||||||
<default-dashboard></default-dashboard>
|
<default-dashboard v-else></default-dashboard>
|
||||||
<!-- </ClientOnly> -->
|
<!-- </ClientOnly> -->
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
||||||
onRequest({ request, options, error }) {
|
onRequest({ request, options, error }) {
|
||||||
options.baseURL =
|
options.baseURL =
|
||||||
import.meta.env.VITE_BASE_URL +
|
import.meta.env.VITE_BASE_URL +
|
||||||
import.meta.env.VITE_API_NAME +
|
import.meta.env.NUXT_PUBLIC_API_NAME+
|
||||||
options.baseURL;
|
options.baseURL;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
|
|
@ -3,12 +3,13 @@ import { useStorage } from "@vueuse/core";
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
export default defineNuxtPlugin((nuxtApp) => {
|
||||||
let token = useStorage("id_token", "GuestAccess").value;
|
let token = useStorage("id_token", "GuestAccess").value;
|
||||||
|
const config = useRuntimeConfig();
|
||||||
|
|
||||||
const api = $fetch.create({
|
const api = $fetch.create({
|
||||||
onRequest({ request, options, error }) {
|
onRequest({ request, options, error }) {
|
||||||
options.baseURL =
|
options.baseURL =
|
||||||
import.meta.env.VITE_BASE_URL +
|
config.public.NUXT_PUBLIC_BASE_URL +
|
||||||
import.meta.env.VITE_API_NAME +
|
config.public.NUXT_PUBLIC_API_NAME +
|
||||||
options.baseURL;
|
options.baseURL;
|
||||||
|
|
||||||
if (token) {
|
if (token) {
|
||||||
|
@ -40,13 +41,14 @@ export default defineNuxtPlugin((nuxtApp) => {
|
||||||
getRequest: (url, options = {}) => api(url, { method: "GET", ...options }),
|
getRequest: (url, options = {}) => api(url, { method: "GET", ...options }),
|
||||||
postRequest: (url, body, options = {}) =>
|
postRequest: (url, body, options = {}) =>
|
||||||
api(url, { method: "POST", body, ...options }),
|
api(url, { method: "POST", body, ...options }),
|
||||||
deleteRequest: (url, options = {}) => api(url, { method: "DELETE", ...options }),
|
deleteRequest: (url, options = {}) =>
|
||||||
|
api(url, { method: "DELETE", ...options }),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Expose to useNuxtApp().$api and useNuxtApp().$http
|
// Expose to useNuxtApp().$api and useNuxtApp().$http
|
||||||
return {
|
return {
|
||||||
provide: {
|
provide: {
|
||||||
http
|
http,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,23 +4,28 @@
|
||||||
// createApp.use(Vuelidate);
|
// createApp.use(Vuelidate);
|
||||||
|
|
||||||
import { useVuelidate } from '@vuelidate/core'
|
import { useVuelidate } from '@vuelidate/core'
|
||||||
import { required, minLength } from '@vuelidate/validators'
|
// import { required, minLength } from '@vuelidate/validators'
|
||||||
|
|
||||||
export default defineNuxtPlugin((nuxtApp) => {
|
// export default defineNuxtPlugin((nuxtApp) => {
|
||||||
nuxtApp.vueApp.use(() => {
|
// nuxtApp.vueApp.use((useVuelidate) => {
|
||||||
// // Example of global setup, but typically you'd handle this in the component
|
// // // Example of global setup, but typically you'd handle this in the component
|
||||||
// const state = reactive({
|
// // const state = reactive({
|
||||||
// firstName: ''
|
// // firstName: ''
|
||||||
|
// // })
|
||||||
|
// // const rules = {
|
||||||
|
// // firstName: {
|
||||||
|
// // required,
|
||||||
|
// // minLength: minLength(2)
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // const v$ = useVuelidate(rules, state)
|
||||||
|
// // return v$;
|
||||||
|
// // // Return the v$ instance or any other necessary setup
|
||||||
|
// })
|
||||||
// })
|
// })
|
||||||
// const rules = {
|
|
||||||
// firstName: {
|
|
||||||
// required,
|
|
||||||
// minLength: minLength(2)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// const v$ = useVuelidate(rules, state)
|
|
||||||
// return v$;
|
|
||||||
// // Return the v$ instance or any other necessary setup
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default defineNuxtPlugin(nuxtApp => {
|
||||||
|
nuxtApp.provide('vuelidate', useVuelidate)
|
||||||
|
})
|
Before Width: | Height: | Size: 490 KiB After Width: | Height: | Size: 490 KiB |
Before Width: | Height: | Size: 783 KiB After Width: | Height: | Size: 783 KiB |
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
Before Width: | Height: | Size: 203 KiB After Width: | Height: | Size: 203 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 186 KiB After Width: | Height: | Size: 186 KiB |
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 550 B |
BIN
public/img/haditha/fav-icons/android-icon-144x144.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
public/img/haditha/fav-icons/android-icon-192x192.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
public/img/haditha/fav-icons/android-icon-36x36.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
public/img/haditha/fav-icons/android-icon-48x48.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
public/img/haditha/fav-icons/android-icon-72x72.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
public/img/haditha/fav-icons/android-icon-96x96.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-114x114.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-120x120.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-144x144.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-152x152.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-180x180.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-57x57.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-60x60.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-72x72.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-76x76.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
public/img/haditha/fav-icons/apple-icon-precomposed.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
public/img/haditha/fav-icons/apple-icon.png
Normal file
After Width: | Height: | Size: 20 KiB |
2
public/img/haditha/fav-icons/browserconfig.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<browserconfig><msapplication><tile><square70x70logo src="/ms-icon-70x70.png"/><square150x150logo src="/ms-icon-150x150.png"/><square310x310logo src="/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>
|
BIN
public/img/haditha/fav-icons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/img/haditha/fav-icons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
public/img/haditha/fav-icons/favicon-96x96.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
public/img/haditha/fav-icons/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
41
public/img/haditha/fav-icons/manifest.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"name": "App",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-36x36.png",
|
||||||
|
"sizes": "36x36",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "0.75"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-48x48.png",
|
||||||
|
"sizes": "48x48",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-72x72.png",
|
||||||
|
"sizes": "72x72",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "1.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-96x96.png",
|
||||||
|
"sizes": "96x96",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-144x144.png",
|
||||||
|
"sizes": "144x144",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "3.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "\/android-icon-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image\/png",
|
||||||
|
"density": "4.0"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
public/img/haditha/fav-icons/ms-icon-144x144.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
public/img/haditha/fav-icons/ms-icon-150x150.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
public/img/haditha/fav-icons/ms-icon-310x310.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
public/img/haditha/fav-icons/ms-icon-70x70.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 304 KiB After Width: | Height: | Size: 304 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
9
public/img/haditha/robot-indicator.svg
Normal file
|
@ -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>
|
After Width: | Height: | Size: 630 B |
Before Width: | Height: | Size: 174 B After Width: | Height: | Size: 174 B |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
public/img/haditha/section-four_card-five.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
public/img/haditha/section-four_card-four.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
public/img/haditha/section-four_card-one.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
public/img/haditha/section-four_card-three.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
public/img/haditha/section-four_card-two.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
public/img/haditha/section-three-bgi.png
Normal file
After Width: | Height: | Size: 1.1 MiB |