Compare commits
No commits in common. "163da9f58923f73d43eae60e7efeb75707cd3686" and "cca8dfc4574377263f3218f4c605133d96f17e5d" have entirely different histories.
163da9f589
...
cca8dfc457
2
.env
2
.env
|
|
@ -2,6 +2,6 @@ NUXT_PUBLIC_API_NAME=api/
|
||||||
|
|
||||||
IS_DEVLOP_MODE=1
|
IS_DEVLOP_MODE=1
|
||||||
|
|
||||||
NUXT_PUBLIC_SYSTEM=tavasi_conflict
|
NUXT_PUBLIC_SYSTEM=monir
|
||||||
NUXT_PUBLIC_BASE_URL=http://192.168.23.160/
|
NUXT_PUBLIC_BASE_URL=http://192.168.23.160/
|
||||||
NUXT_PUBLIC_BASE_URL2=https://hamfahmi.ir/
|
NUXT_PUBLIC_BASE_URL2=https://hamfahmi.ir/
|
||||||
|
|
@ -2,5 +2,5 @@
|
||||||
NUXT_PUBLIC_SYSTEM=majles
|
NUXT_PUBLIC_SYSTEM=majles
|
||||||
|
|
||||||
# (اختیاری)
|
# (اختیاری)
|
||||||
NUXT_PUBLIC_SYSTEM=tavasi_conflict
|
NUXT_PUBLIC_APP_NAME=Majles System
|
||||||
NUXT_PUBLIC_BASE_URL=https://192.168.23.160/
|
NUXT_PUBLIC_BASE_URL=http://192.168.23.160/
|
||||||
|
|
@ -185,6 +185,7 @@ onMounted(fetchItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.i-lucide\:check {
|
.i-lucide\:check {
|
||||||
display: none;
|
color: #22c55e;
|
||||||
|
stroke: #22c55e;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- تولبار ادیتور -->
|
<!-- تولبار ادیتور -->
|
||||||
<!-- <div class="editor-toolbar" v-if="editor">
|
<div class="editor-toolbar" v-if="editor">
|
||||||
<div
|
<div
|
||||||
class="toolbar-group"
|
class="toolbar-group"
|
||||||
v-for="(group, gIndex) in toolbarGroups"
|
v-for="(group, gIndex) in toolbarGroups"
|
||||||
|
|
@ -12,13 +12,15 @@
|
||||||
:key="index"
|
:key="index"
|
||||||
@click="btn.action(editor)"
|
@click="btn.action(editor)"
|
||||||
:class="{ 'is-active': btn.isActive ? btn.isActive(editor) : false }"
|
:class="{ 'is-active': btn.isActive ? btn.isActive(editor) : false }"
|
||||||
:disabled="readOnly || (btn.disabled ? btn.disabled(editor) : false)"
|
:disabled="btn.disabled ? !btn.disabled(editor) : false"
|
||||||
:title="btn.title"
|
:title="btn.title"
|
||||||
>
|
>
|
||||||
<span class="toolbar-icon">{{ btn.icon }}</span>
|
<span class="toolbar-icon">{{ btn.icon }}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
|
|
||||||
|
<!-- محتوای ادیتور -->
|
||||||
<editor-content :editor="editor" class="editor-content" />
|
<editor-content :editor="editor" class="editor-content" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -40,10 +42,6 @@ const props = defineProps({
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
readOnly: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const editor = ref(null);
|
const editor = ref(null);
|
||||||
|
|
@ -251,42 +249,40 @@ function generateDetailsHtml(item) {
|
||||||
let html = `<details class="custom-details" ${item.isOpen ? "open" : ""}>`;
|
let html = `<details class="custom-details" ${item.isOpen ? "open" : ""}>`;
|
||||||
html += `<summary>`;
|
html += `<summary>`;
|
||||||
if (item.tag) {
|
if (item.tag) {
|
||||||
html += `<a class="tag" target="normal" @click.stop="true" > ${item.tag} </a>`;
|
html += `<span class="tag" > ${item.tag} </span>`;
|
||||||
// console.log(" html 1 ", html);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `${item.title || "بدون عنوان"}`;
|
html += `${item.title || "بدون عنوان"}`;
|
||||||
if (item.link_url) {
|
if (item.link_url) {
|
||||||
html += `<a class="link-url" href="${item.link_url}">${item.link_label}</a>`;
|
html += `<a class="link-url" href="${item.link_url}">${item.link_label}</a>`;
|
||||||
}
|
}
|
||||||
html += `</summary>`;
|
html += "</summary>";
|
||||||
|
|
||||||
html += formatContent(item.content || "");
|
const formattedContent = formatContent(item.content || "");
|
||||||
|
html += `<div class="details-content">${formattedContent}</div>`;
|
||||||
|
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
|
html += '<div class="children-container">';
|
||||||
item.children.forEach((child) => {
|
item.children.forEach((child) => {
|
||||||
html += generateDetailsHtml(child);
|
html += generateDetailsHtml(child);
|
||||||
});
|
});
|
||||||
|
html += "</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
html += `</details>`;
|
html += `</details>`;
|
||||||
|
|
||||||
// console.log(" html 10 ", html);
|
|
||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadFromJson() {
|
function loadFromJson() {
|
||||||
if (!editor.value) return;
|
if (!editor.value) return;
|
||||||
|
|
||||||
let html = "";
|
let html =
|
||||||
|
'<p style="margin-bottom: 1.5rem; color: var(--color-dark-primary-700);"></p>';
|
||||||
|
|
||||||
props.accordionData.forEach((item) => {
|
props.accordionData.forEach((item) => {
|
||||||
html += generateDetailsHtml(item);
|
html += generateDetailsHtml(item);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('loadFromJson ', html);
|
|
||||||
|
|
||||||
editor.value.commands.setContent(html);
|
editor.value.commands.setContent(html);
|
||||||
}
|
}
|
||||||
watch(
|
watch(
|
||||||
|
|
@ -295,7 +291,7 @@ watch(
|
||||||
if (!editor.value) return;
|
if (!editor.value) return;
|
||||||
if (!newVal || newVal.length === 0) return;
|
if (!newVal || newVal.length === 0) return;
|
||||||
|
|
||||||
// console.log("accordionData updated:", newVal);
|
console.log("accordionData updated:", newVal);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
loadFromJson();
|
loadFromJson();
|
||||||
|
|
@ -305,7 +301,6 @@ watch(
|
||||||
);
|
);
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
editor.value = new Editor({
|
editor.value = new Editor({
|
||||||
editable: !props.readOnly,
|
|
||||||
extensions: [
|
extensions: [
|
||||||
StarterKit,
|
StarterKit,
|
||||||
Underline,
|
Underline,
|
||||||
|
|
@ -439,7 +434,7 @@ onBeforeUnmount(() => {
|
||||||
|
|
||||||
.tiptap {
|
.tiptap {
|
||||||
font-family:
|
font-family:
|
||||||
"sahel",
|
"Vazir",
|
||||||
"Inter",
|
"Inter",
|
||||||
-apple-system,
|
-apple-system,
|
||||||
BlinkMacSystemFont,
|
BlinkMacSystemFont,
|
||||||
|
|
@ -559,9 +554,11 @@ onBeforeUnmount(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
summary.tag {
|
summary.tag {
|
||||||
color: blue;
|
color: blue;
|
||||||
border-radius: var(--radius) var(--radius) 0 0;
|
border-radius: var(--radius) var(--radius) 0 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
summary.label {
|
summary.label {
|
||||||
|
|
|
||||||
|
|
@ -1,371 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="bg-white dark:bg-dark-primary-800 flex items-center justify-center p-4"
|
|
||||||
>
|
|
||||||
<!-- Container -->
|
|
||||||
<div class="w-full max-w-sm space-y-6">
|
|
||||||
<!-- Header -->
|
|
||||||
<div class="text-center space-y-1">
|
|
||||||
<div
|
|
||||||
class="w-12 h-12 mx-auto mb-3 dark:bg-primary-800 rounded-full flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<!-- <span class="text-white text-lg font-bold">پ</span> -->
|
|
||||||
<img :src="useSystemTheme.logo.value" alt="" class="h-9 w-9" />
|
|
||||||
</div>
|
|
||||||
<h1 class="text-xl font-medium text-primary-900 dark:text-white">
|
|
||||||
ورود به حساب
|
|
||||||
</h1>
|
|
||||||
<!-- <p class="text-xs text-primary-400 dark:text-primary-400">
|
|
||||||
زیستبوم پژوهشگران
|
|
||||||
</p> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Form -->
|
|
||||||
<div class="space-y-3">
|
|
||||||
<!-- Username -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>نام کاربری یا ایمیل</label
|
|
||||||
>
|
|
||||||
<div class="relative">
|
|
||||||
<UIcon
|
|
||||||
name="i-heroicons-envelope"
|
|
||||||
class="absolute right-2 top-1/2 transform -translate-y-1/2 text-primary-400 dark:text-primary-500 w-4 h-4"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
v-model="username"
|
|
||||||
type="text"
|
|
||||||
placeholder="example@domain.com"
|
|
||||||
class="w-full px-3 py-2 pr-10 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Password -->
|
|
||||||
<div>
|
|
||||||
<div class="flex justify-between items-center mb-1">
|
|
||||||
<label
|
|
||||||
class="text-xs font-medium text-primary-700 dark:text-primary-300"
|
|
||||||
>رمز عبور</label
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
@click.prevent="goForgotPassword"
|
|
||||||
class="text-xs text-primary-500 dark:text-primary-400 hover:text-primary-700 dark:hover:text-primary-300"
|
|
||||||
>
|
|
||||||
فراموش کردهاید؟
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<UIcon
|
|
||||||
name="i-heroicons-lock-closed"
|
|
||||||
class="absolute right-2 top-1/2 transform -translate-y-1/2 text-primary-400 dark:text-primary-500 w-4 h-4"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
v-model="password"
|
|
||||||
:type="showPassword ? 'text' : 'password'"
|
|
||||||
placeholder="••••••••"
|
|
||||||
class="w-full px-3 py-2 pr-10 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="showPassword = !showPassword"
|
|
||||||
class="absolute left-2 top-1/2 transform -translate-y-1/2 text-primary-400 dark:text-primary-500 hover:text-primary-600 dark:hover:text-primary-400"
|
|
||||||
>
|
|
||||||
<UIcon
|
|
||||||
:name="
|
|
||||||
showPassword ? 'i-heroicons-eye-slash' : 'i-heroicons-eye'
|
|
||||||
"
|
|
||||||
class="w-4 h-4 mt-1"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CAPTCHA -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>کد امنیتی</label
|
|
||||||
>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<div class="flex-1">
|
|
||||||
<input
|
|
||||||
v-model="captcha"
|
|
||||||
type="text"
|
|
||||||
placeholder="کد را وارد کنید"
|
|
||||||
class="w-full px-3 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500 text-center"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<div
|
|
||||||
class="w-24 h-10 border border-primary-300 dark:border-primary-700 rounded overflow-hidden bg-primary-50 dark:bg-primary-800 flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="captchaImage"
|
|
||||||
alt="کد امنیتی"
|
|
||||||
class="w-full h-full object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
@click="resetCaptcha"
|
|
||||||
:disabled="loadingCaptcha"
|
|
||||||
class="w-8 h-8 border border-primary-300 dark:border-primary-700 rounded flex items-center justify-center hover:bg-primary-50 dark:hover:bg-primary-800 disabled:opacity-50 text-primary-700 dark:text-primary-300"
|
|
||||||
>
|
|
||||||
<UIcon
|
|
||||||
name="i-heroicons-arrow-path"
|
|
||||||
class="w-4 h-4"
|
|
||||||
:class="{ 'animate-spin': loadingCaptcha }"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Login Button -->
|
|
||||||
<button
|
|
||||||
@click="handleLogin"
|
|
||||||
:disabled="loading"
|
|
||||||
class="w-full py-2.5 bg-primary dark:bg-primary-800 text-white text-sm font-medium rounded hover:bg-primary-600 dark:hover:bg-primary-700 active:bg-primary-900 dark:active:bg-dark-primary-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
||||||
>
|
|
||||||
<span v-if="loading" class="flex items-center justify-center gap-2">
|
|
||||||
<UIcon name="i-heroicons-arrow-path" class="w-4 h-4 animate-spin" />
|
|
||||||
در حال ورود...
|
|
||||||
</span>
|
|
||||||
<span v-else> ورود </span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Divider -->
|
|
||||||
<div class="relative">
|
|
||||||
<div class="absolute inset-0 flex items-center">
|
|
||||||
<div
|
|
||||||
class="w-full border-t border-primary-200 dark:border-primary-700"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<div class="relative flex justify-center text-xs">
|
|
||||||
<span
|
|
||||||
class="px-2 bg-white dark:bg-primary-900 text-primary-500 dark:text-primary-400"
|
|
||||||
>یا</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Alternative Options -->
|
|
||||||
<div class="space-y-2">
|
|
||||||
<button
|
|
||||||
@click="goLoginPhonePage(false)"
|
|
||||||
class="w-full py-2 border border-primary-300 dark:border-primary-700 text-primary-700 dark:text-primary-300 text-sm font-medium rounded hover:bg-primary-50 dark:hover:bg-primary-800 transition-colors"
|
|
||||||
>
|
|
||||||
ورود با شماره تلفن
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
@click="loginGuest"
|
|
||||||
class="w-full py-2 border border-primary-300 dark:border-primary-700 text-primary-700 dark:text-primary-300 text-sm font-medium rounded hover:bg-primary-50 dark:hover:bg-primary-800 transition-colors"
|
|
||||||
>
|
|
||||||
ورود به عنوان مهمان
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Footer Note -->
|
|
||||||
<p
|
|
||||||
class="text-xs text-primary-400 dark:text-primary-500 text-center pt-4"
|
|
||||||
>
|
|
||||||
با ورود، با
|
|
||||||
<a
|
|
||||||
href="#"
|
|
||||||
class="text-primary-600 dark:text-primary-400 hover:text-primary-800 dark:hover:text-primary-300"
|
|
||||||
>قوانین</a
|
|
||||||
>
|
|
||||||
موافقت میکنید
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from "vue";
|
|
||||||
import { useAuthStore } from "@/stores/authStore";
|
|
||||||
import { useNuxtApp } from "#app";
|
|
||||||
import { navigateTo } from "#imports";
|
|
||||||
import { useToast } from "#imports";
|
|
||||||
import { composSystemTheme } from "@/composables/composSystemTheme";
|
|
||||||
import { getUserPermission } from "@/stores/permissionStore";
|
|
||||||
|
|
||||||
const useSystemTheme = composSystemTheme();
|
|
||||||
const toast = useToast();
|
|
||||||
|
|
||||||
// --- State ---
|
|
||||||
const username = ref("");
|
|
||||||
const password = ref("");
|
|
||||||
const captcha = ref("");
|
|
||||||
const captchaImage = ref("");
|
|
||||||
const loading = ref(false);
|
|
||||||
const loadingCaptcha = ref(false);
|
|
||||||
const showPassword = ref(false);
|
|
||||||
|
|
||||||
// --- Nuxt App & Store ---
|
|
||||||
const nuxtApp = useNuxtApp();
|
|
||||||
const { $http: httpService } = nuxtApp;
|
|
||||||
const authStore = useAuthStore();
|
|
||||||
|
|
||||||
// --- Navigation ---
|
|
||||||
const goLoginPhonePage = (isReset) => {
|
|
||||||
navigateTo("/loginphone");
|
|
||||||
};
|
|
||||||
|
|
||||||
const goForgotPassword = () => {
|
|
||||||
navigateTo("/forget");
|
|
||||||
};
|
|
||||||
|
|
||||||
const loginGuest = () => {
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
httpService
|
|
||||||
.getRequest("/login/user/validate", {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
Authorization: "GuestAccess",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
authStore.setUser(res);
|
|
||||||
|
|
||||||
const userPermissionStore = getUserPermission();
|
|
||||||
userPermissionStore.fetchUserPermissions();
|
|
||||||
// console.log("Permissions:", userPermissionStore.permissions);
|
|
||||||
toast.add({
|
|
||||||
title: res.message || "ورود موفقیتآمیز بود",
|
|
||||||
icon: "i-lucide-calendar-days",
|
|
||||||
});
|
|
||||||
|
|
||||||
navigateTo({
|
|
||||||
name: "DashboardBasePage",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log("error ==> ", error);
|
|
||||||
|
|
||||||
toast.add({
|
|
||||||
title: "خطا",
|
|
||||||
description: "خطا در ورود",
|
|
||||||
color: "red",
|
|
||||||
});
|
|
||||||
|
|
||||||
loadCaptcha();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// toast.add({
|
|
||||||
// title: "خطا",
|
|
||||||
// description: "ورود به عنوان مهمان در حال توسعه است",
|
|
||||||
// color: "red",
|
|
||||||
// });
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- CAPTCHA ---
|
|
||||||
const loadCaptcha = async () => {
|
|
||||||
loadingCaptcha.value = true;
|
|
||||||
try {
|
|
||||||
const string = await httpService.getRequest("/login/captcha/makeimage");
|
|
||||||
captchaImage.value = `data:image/jpeg;base64,${string}`;
|
|
||||||
} catch {
|
|
||||||
captchaImage.value = "/assets/common/img/captcha.png";
|
|
||||||
} finally {
|
|
||||||
loadingCaptcha.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const resetCaptcha = () => {
|
|
||||||
loadCaptcha();
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- Login Logic ---
|
|
||||||
const handleLogin = () => {
|
|
||||||
loading.value = true;
|
|
||||||
|
|
||||||
const formData = {
|
|
||||||
username: username.value,
|
|
||||||
password: password.value,
|
|
||||||
captcha: captcha.value,
|
|
||||||
};
|
|
||||||
|
|
||||||
httpService
|
|
||||||
.postRequest("/login/user/login", formData)
|
|
||||||
.then((res) => {
|
|
||||||
authStore.setUser(res);
|
|
||||||
|
|
||||||
const userPermissionStore = getUserPermission();
|
|
||||||
userPermissionStore.fetchUserPermissions();
|
|
||||||
// console.log("Permissions:", userPermissionStore.permissions);
|
|
||||||
toast.add({
|
|
||||||
title: res.message || "ورود موفقیتآمیز بود",
|
|
||||||
icon: "i-lucide-calendar-days",
|
|
||||||
});
|
|
||||||
|
|
||||||
navigateTo({
|
|
||||||
name: "DashboardBasePage",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log("error ==> ", error);
|
|
||||||
|
|
||||||
toast.add({
|
|
||||||
title: "خطا",
|
|
||||||
description: "خطا در ورود",
|
|
||||||
color: "red",
|
|
||||||
});
|
|
||||||
|
|
||||||
loadCaptcha();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadCaptcha();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
input:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* بهبود نمایش در حالت دارک مود */
|
|
||||||
/* @media (prefers-color-scheme: dark) {
|
|
||||||
.dark\:bg-primary-900 {
|
|
||||||
background-color: #111827;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:bg-primary-800 {
|
|
||||||
background-color: #1f2937;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:border-primary-700 {
|
|
||||||
border-color: #374151;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:text-white {
|
|
||||||
color: #f9fafb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:text-primary-300 {
|
|
||||||
color: #d1d5db;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark\:placeholder-primary-500 {
|
|
||||||
&::placeholder {
|
|
||||||
color: #6b7280;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,394 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
class="bg-white dark:bg-dark-primary-800 flex items-center justify-center p-4"
|
|
||||||
>
|
|
||||||
<!-- Container -->
|
|
||||||
<div class="w-full max-w-md space-y-6">
|
|
||||||
<!-- Header -->
|
|
||||||
<div class="text-center space-y-1">
|
|
||||||
<div
|
|
||||||
class="w-12 h-12 mx-auto mb-3 dark:bg-primary-800 rounded-full flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<!-- <span class="text-white text-lg font-bold">پ</span> -->
|
|
||||||
<img :src="useSystemTheme.logo.value" alt="" class="h-9 w-9" />
|
|
||||||
</div>
|
|
||||||
<h1 class="text-xl font-medium text-primary-900 dark:text-white">
|
|
||||||
ایجاد حساب کاربری
|
|
||||||
</h1>
|
|
||||||
<!-- <p class="text-xs text-primary-400 dark:text-primary-400">زیستبوم پژوهشگران</p> -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Form -->
|
|
||||||
<div class="space-y-3">
|
|
||||||
<!-- Name & Last Name -->
|
|
||||||
<div class="grid grid-cols-2 gap-3">
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>نام</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model.trim="name"
|
|
||||||
type="text"
|
|
||||||
placeholder="نام"
|
|
||||||
class="w-full px-3 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
/>
|
|
||||||
<p v-if="showError(v$.name)" class="mt-1 text-xs text-red-500">
|
|
||||||
الزامی
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>نام خانوادگی</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model.trim="last_name"
|
|
||||||
type="text"
|
|
||||||
placeholder="نام خانوادگی"
|
|
||||||
class="w-full px-3 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
/>
|
|
||||||
<p v-if="showError(v$.last_name)" class="mt-1 text-xs text-red-500">
|
|
||||||
الزامی
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Username -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>نام کاربری</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model.trim="username"
|
|
||||||
type="text"
|
|
||||||
placeholder="نام کاربری"
|
|
||||||
class="w-full px-5 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
<p v-if="showError(v$.username)" class="mt-1 text-xs text-red-500">
|
|
||||||
الزامی
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Email -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>ایمیل</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model.trim="email"
|
|
||||||
type="email"
|
|
||||||
placeholder="example@domain.com"
|
|
||||||
class="w-full px-5 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
<p v-if="showError(v$.email)" class="mt-1 text-xs text-red-500">
|
|
||||||
ایمیل معتبر
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Password -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>رمز عبور</label
|
|
||||||
>
|
|
||||||
<div class="relative">
|
|
||||||
<input
|
|
||||||
v-model.trim="password"
|
|
||||||
:type="passwordFieldType"
|
|
||||||
placeholder="••••••••"
|
|
||||||
class="w-full px-3 py-2 pr-10 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
@focus="isFocusedOnPassword = true"
|
|
||||||
@blur="isFocusedOnPassword = false"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="togglePasswordVisibility"
|
|
||||||
class="absolute left-2 top-1/2 transform -translate-y-1/2 text-primary-400 dark:text-primary-500 hover:text-primary-600 dark:hover:text-primary-400"
|
|
||||||
>
|
|
||||||
<!-- <span v-if="isPasswordVisible">👁</span>
|
|
||||||
<span v-else>👁🗨</span> -->
|
|
||||||
<UIcon
|
|
||||||
:name="
|
|
||||||
isPasswordVisible
|
|
||||||
? 'i-heroicons-eye-slash'
|
|
||||||
: 'i-heroicons-eye'
|
|
||||||
"
|
|
||||||
class="w-4 h-4 mt-1"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Password rules -->
|
|
||||||
<div
|
|
||||||
v-if="isFocusedOnPassword"
|
|
||||||
class="mt-2 p-2 border border-primary-200 dark:border-primary-700 rounded bg-primary-50 dark:bg-primary-800 text-xs space-y-1"
|
|
||||||
>
|
|
||||||
<div :class="ruleClass(v$.password.minLength)">
|
|
||||||
• حداقل ۸ کاراکتر
|
|
||||||
</div>
|
|
||||||
<div :class="ruleClass(v$.password.hasLowerCase)">
|
|
||||||
• حرف کوچک انگلیسی
|
|
||||||
</div>
|
|
||||||
<div :class="ruleClass(v$.password.hasUpperCase)">
|
|
||||||
• حرف بزرگ انگلیسی
|
|
||||||
</div>
|
|
||||||
<div :class="ruleClass(v$.password.hasSpecialChar)">
|
|
||||||
• کاراکتر خاص (!@#$%^&*)
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Repeat Password -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>تکرار رمز عبور</label
|
|
||||||
>
|
|
||||||
<div class="relative">
|
|
||||||
<input
|
|
||||||
v-model.trim="repassword"
|
|
||||||
:type="repasswordFieldType"
|
|
||||||
placeholder="••••••••"
|
|
||||||
class="w-full px-3 py-2 pr-10 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="toggleRepasswordVisibility"
|
|
||||||
class="absolute left-2 top-1/2 transform -translate-y-1/2 text-primary-400 dark:text-primary-500 hover:text-primary-600 dark:hover:text-primary-400"
|
|
||||||
>
|
|
||||||
<!-- <span v-if="isRepasswordVisible">👁</span>
|
|
||||||
<span v-else>👁🗨</span> -->
|
|
||||||
<UIcon
|
|
||||||
:name="
|
|
||||||
isRepasswordVisible
|
|
||||||
? 'i-heroicons-eye-slash'
|
|
||||||
: 'i-heroicons-eye'
|
|
||||||
"
|
|
||||||
class="w-4 h-4 mt-1"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CAPTCHA -->
|
|
||||||
<div>
|
|
||||||
<label
|
|
||||||
class="block text-xs font-medium text-primary-700 dark:text-primary-300 mb-1"
|
|
||||||
>کد امنیتی</label
|
|
||||||
>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<div class="flex-1">
|
|
||||||
<input
|
|
||||||
v-model.trim="captcha"
|
|
||||||
type="text"
|
|
||||||
placeholder="کد را وارد کنید"
|
|
||||||
class="w-full px-3 py-2 text-sm border border-primary-300 dark:border-primary-700 rounded focus:outline-none focus:ring-1 focus:ring-primary-400 dark:focus:ring-primary-600 focus:border-transparent bg-white dark:bg-primary-800 text-primary-900 dark:text-white placeholder-primary-400 dark:placeholder-primary-500 text-center"
|
|
||||||
dir="rtl"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<div
|
|
||||||
class="w-24 h-10 border border-primary-300 dark:border-primary-700 rounded overflow-hidden bg-primary-50 dark:bg-primary-800 flex items-center justify-center"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
:src="captchaImage"
|
|
||||||
alt="کد امنیتی"
|
|
||||||
class="w-full h-full object-contain"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
@click="getCaptcha"
|
|
||||||
class="w-8 h-8 border border-primary-300 dark:border-primary-700 rounded flex items-center justify-center hover:bg-primary-50 dark:hover:bg-primary-800 text-primary-700 dark:text-primary-300"
|
|
||||||
>
|
|
||||||
↻
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p v-if="showError(v$.captcha)" class="mt-1 text-xs text-red-500">
|
|
||||||
الزامی
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Errors -->
|
|
||||||
<div
|
|
||||||
v-if="submitStatus === 'ERROR'"
|
|
||||||
class="text-xs text-red-500 space-y-0.5"
|
|
||||||
>
|
|
||||||
<p v-if="v$.password.required.$invalid">• رمز عبور الزامی است</p>
|
|
||||||
<p v-if="v$.password.minLength.$invalid">
|
|
||||||
• رمز عبور حداقل ۸ کاراکتر
|
|
||||||
</p>
|
|
||||||
<p v-if="v$.repassword.required.$invalid">• تکرار رمز الزامی است</p>
|
|
||||||
<p v-if="v$.repassword.sameAsPassword.$invalid">
|
|
||||||
• رمزها یکسان نیستند
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Register Error -->
|
|
||||||
<p v-if="registerError" class="text-xs text-red-500">
|
|
||||||
{{ registerError }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<!-- Submit Button -->
|
|
||||||
<button
|
|
||||||
:disabled="loading"
|
|
||||||
@click="submitRegister"
|
|
||||||
class="w-full py-2.5 bg-primary-900 dark:bg-primary-800 text-white text-sm font-medium rounded hover:bg-primary-800 dark:hover:bg-primary-700 active:bg-primary-900 dark:active:bg-primary-800 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
|
||||||
>
|
|
||||||
{{ loading ? "در حال ایجاد حساب..." : "ایجاد حساب" }}
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<!-- Login Link -->
|
|
||||||
<div
|
|
||||||
class="text-center pt-4 border-t border-primary-200 dark:border-primary-700"
|
|
||||||
>
|
|
||||||
<p class="text-xs text-primary-500 dark:text-primary-400">
|
|
||||||
قبلاً حساب دارید؟
|
|
||||||
<a
|
|
||||||
href="/login"
|
|
||||||
class="text-primary-700 dark:text-primary-300 hover:text-primary-900 dark:hover:text-white font-medium"
|
|
||||||
>
|
|
||||||
ورود
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, computed, onMounted } from "vue";
|
|
||||||
import useVuelidate from "@vuelidate/core";
|
|
||||||
import { required, minLength, sameAs } from "@vuelidate/validators";
|
|
||||||
import { useNuxtApp } from "#app";
|
|
||||||
import { navigateTo } from "#imports";
|
|
||||||
import { composSystemTheme } from "@/composables/composSystemTheme";
|
|
||||||
|
|
||||||
const useSystemTheme = composSystemTheme();
|
|
||||||
|
|
||||||
const name = ref("");
|
|
||||||
const last_name = ref("");
|
|
||||||
const username = ref("");
|
|
||||||
const email = ref("");
|
|
||||||
const password = ref("");
|
|
||||||
const repassword = ref("");
|
|
||||||
const captcha = ref("");
|
|
||||||
|
|
||||||
const captchaImage = ref("");
|
|
||||||
const isFocusedOnPassword = ref(false);
|
|
||||||
const isPasswordVisible = ref(false);
|
|
||||||
const isRepasswordVisible = ref(false);
|
|
||||||
const submitStatus = ref(null);
|
|
||||||
const loading = ref(false);
|
|
||||||
const registerError = ref("");
|
|
||||||
|
|
||||||
const rules = {
|
|
||||||
name: { required },
|
|
||||||
last_name: { required },
|
|
||||||
username: { required },
|
|
||||||
email: { required },
|
|
||||||
password: {
|
|
||||||
required,
|
|
||||||
minLength: minLength(8),
|
|
||||||
hasLowerCase: (v) => /[a-z]/.test(v),
|
|
||||||
hasUpperCase: (v) => /[A-Z]/.test(v),
|
|
||||||
hasSpecialChar: (v) => /[!@#$%^&*]/.test(v),
|
|
||||||
},
|
|
||||||
repassword: {
|
|
||||||
required,
|
|
||||||
sameAsPassword: sameAs(password),
|
|
||||||
},
|
|
||||||
captcha: { required },
|
|
||||||
};
|
|
||||||
|
|
||||||
const v$ = useVuelidate(rules, {
|
|
||||||
name,
|
|
||||||
last_name,
|
|
||||||
username,
|
|
||||||
email,
|
|
||||||
password,
|
|
||||||
repassword,
|
|
||||||
captcha,
|
|
||||||
});
|
|
||||||
|
|
||||||
const passwordFieldType = computed(() =>
|
|
||||||
isPasswordVisible.value ? "text" : "password"
|
|
||||||
);
|
|
||||||
const repasswordFieldType = computed(() =>
|
|
||||||
isRepasswordVisible.value ? "text" : "password"
|
|
||||||
);
|
|
||||||
const togglePasswordVisibility = () =>
|
|
||||||
(isPasswordVisible.value = !isPasswordVisible.value);
|
|
||||||
const toggleRepasswordVisibility = () =>
|
|
||||||
(isRepasswordVisible.value = !isRepasswordVisible.value);
|
|
||||||
const showError = (field) => submitStatus.value === "ERROR" && field.$invalid;
|
|
||||||
const ruleClass = (rule) => (rule.$invalid ? "text-red-500" : "text-green-600");
|
|
||||||
|
|
||||||
const getCaptcha = async () => {
|
|
||||||
try {
|
|
||||||
const { $http } = useNuxtApp();
|
|
||||||
const res = await $http.getRequest("/login/captcha/makeimage");
|
|
||||||
captchaImage.value = `data:image/jpeg;base64,${res}`;
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
captchaImage.value = "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
onMounted(getCaptcha);
|
|
||||||
|
|
||||||
const submitRegister = async () => {
|
|
||||||
const isValid = await v$.value.$validate();
|
|
||||||
if (!isValid) {
|
|
||||||
submitStatus.value = "ERROR";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = true;
|
|
||||||
submitStatus.value = "PENDING";
|
|
||||||
registerError.value = "";
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { $http } = useNuxtApp();
|
|
||||||
const baseUrl = import.meta.env.VITE_AUTH_BASE_URL;
|
|
||||||
|
|
||||||
const res = await $http.postRequest("login/user/register", {
|
|
||||||
name: name.value,
|
|
||||||
last_name: last_name.value,
|
|
||||||
username: username.value,
|
|
||||||
email: email.value,
|
|
||||||
password: password.value,
|
|
||||||
captcha: captcha.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
// ذخیره تو localStorage
|
|
||||||
const id_token = useStorage("id_token", "");
|
|
||||||
id_token.value = res.data.token;
|
|
||||||
|
|
||||||
const userStorage = useStorage("user", {});
|
|
||||||
userStorage.value = res.data;
|
|
||||||
|
|
||||||
navigateTo({
|
|
||||||
name: "DashboardBasePage",
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
registerError.value = err?.response?.data?.message || err.message;
|
|
||||||
await getCaptcha();
|
|
||||||
} finally {
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
input:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -43,20 +43,19 @@ const setDataEditor = async () => {
|
||||||
|
|
||||||
let base_url = window.location.origin;
|
let base_url = window.location.origin;
|
||||||
base_url = base_url.replace("localhost:3007", "localhost:8082");
|
base_url = base_url.replace("localhost:3007", "localhost:8082");
|
||||||
base_url = base_url.replace("jedit.tavasi.ir", "majles.tavasi.ir");
|
base_url = base_url.replace("majles.tavasi.ir", "jedit.tavasi.ir");
|
||||||
base_url = base_url.replace("192.168.23.112:3000", "majles.tavasi.ir");
|
|
||||||
|
|
||||||
base_url += "/entity/show/view/qasection/{{qanon_id}}?jump_id={{section_id}}";
|
base_url += "/entity/show/view/qasection/{{qanon_id}}?jump_id={{section_id}}";
|
||||||
|
|
||||||
accordionItems.value = [];
|
accordionItems.value = [];
|
||||||
let node = {};
|
let node = {}
|
||||||
|
|
||||||
if (_source.previous_info) {
|
if (_source.previous_info) {
|
||||||
let item = _source.previous_info;
|
let item = _source.previous_info;
|
||||||
node = {
|
node = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
id: item.section_mom_id,
|
id: item.section_mom_id,
|
||||||
title: `<a class="label" href="#">قانون مقدم : </a>` + item.qanon_title + " - " + item.full_path,
|
title: `<span class="label">قانون مقدم : </span>` + item.qanon_title + " > " + item.full_path,
|
||||||
tag: item.state_etebar,
|
tag: item.state_etebar,
|
||||||
content: _source.content1,
|
content: _source.content1,
|
||||||
link_label: "«منبع»",
|
link_label: "«منبع»",
|
||||||
|
|
@ -91,7 +90,7 @@ const setDataEditor = async () => {
|
||||||
node = {
|
node = {
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
id: item.section_mom_id,
|
id: item.section_mom_id,
|
||||||
title: `<a class="label">قانون موخر : </a>` + item.qanon_title + " - " + item.full_path,
|
title: `<span class="label">قانون موخر : </span>` + item.qanon_title + " > " + item.full_path,
|
||||||
tag: item.state_etebar,
|
tag: item.state_etebar,
|
||||||
content: _source.content2,
|
content: _source.content2,
|
||||||
link_label: "«منبع»",
|
link_label: "«منبع»",
|
||||||
|
|
@ -127,15 +126,17 @@ const setDataEditor = async () => {
|
||||||
title: "توضیح هوشمند برای وجود وحدت موضوع بین احکام استنادی ",
|
title: "توضیح هوشمند برای وجود وحدت موضوع بین احکام استنادی ",
|
||||||
content: _source.subject_unity.reason,
|
content: _source.subject_unity.reason,
|
||||||
children: [],
|
children: [],
|
||||||
};
|
}
|
||||||
|
|
||||||
if(_source.subject_unity.description){
|
if(_source.subject_unity.description){
|
||||||
|
|
||||||
node["children"].push({
|
node["children"].push({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
id: _source.context_id,
|
id: item.context_id,
|
||||||
title: "شرط اعتبار وحدت موضوع : ",
|
title: "شرط اعتبار وحدت موضوع : ",
|
||||||
content: _source.subject_unity.description,
|
content: _source.subject_unity.description,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accordionItems.value.push(node);
|
accordionItems.value.push(node);
|
||||||
|
|
@ -146,23 +147,23 @@ const setDataEditor = async () => {
|
||||||
title: "توضیح وجود تخالف بین دو ماده ",
|
title: "توضیح وجود تخالف بین دو ماده ",
|
||||||
content: _source.conflict_detection.description,
|
content: _source.conflict_detection.description,
|
||||||
children: [],
|
children: [],
|
||||||
};
|
}
|
||||||
|
|
||||||
accordionItems.value.push(node);
|
accordionItems.value.push(node);
|
||||||
/////-------------بیان نوع تخالف----------------------
|
/////-------------بیان نوع تخالف----------------------
|
||||||
node = {
|
node = {
|
||||||
isOpen: true,
|
isOpen: true,
|
||||||
id: 11,
|
id: 11,
|
||||||
title:
|
title: "بیان نوع تخالف بین دو ماده : " + _source.conflict_relation_identification.main_type,
|
||||||
"بیان نوع تخالف بین دو ماده : " +
|
|
||||||
_source.conflict_relation_identification.main_type,
|
|
||||||
content: _source.conflict_relation_identification.description,
|
content: _source.conflict_relation_identification.description,
|
||||||
children: [],
|
children: [],
|
||||||
};
|
}
|
||||||
|
|
||||||
accordionItems.value.push(node);
|
accordionItems.value.push(node);
|
||||||
/////-----------------------------------
|
/////-----------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log("accordionItems", accordionItems.value);
|
console.log("accordionItems", accordionItems.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,8 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
"dev": "nuxt dev",
|
|
||||||
"dev-tavasi": "env-cmd -f .env.tavasi nuxt dev --host --port 3007 --inspect",
|
"dev-tavasi": "env-cmd -f .env.tavasi nuxt dev --host --port 3007 --inspect",
|
||||||
"build-tavasi": "env-cmd -f .env.tavasi nuxt build --host --inspect",
|
"dev": "nuxt dev"
|
||||||
"build-majles": "env-cmd -f .env.majles nuxt build --host --inspect"
|
|
||||||
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/meteor-icons": "^1.2.1",
|
"@iconify-json/meteor-icons": "^1.2.1",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user