Merge remote-tracking branch 'origin/main' into Baghi/conflict

This commit is contained in:
Baghi330 2026-02-14 15:42:24 +03:30
commit 5cb4b9aff6
4 changed files with 782 additions and 6 deletions

View File

@ -249,9 +249,10 @@ 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 += `<span>${item.tag}</span> `; html += `<span class="tag" > ${item.tag} </span>`;
} }
html += `${escapeHtml(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>`;
} }
@ -550,6 +551,16 @@ onBeforeUnmount(() => {
} }
} }
summary.tag {
color: blue;
border-radius: var(--radius) var(--radius) 0 0;
}
summary.label {
color: chocolate;
font-weight: 700;
}
summary { summary {
position: relative; position: relative;
padding: 1.25rem 1.25rem 1.25rem 3.5rem; padding: 1.25rem 1.25rem 1.25rem 3.5rem;
@ -560,7 +571,6 @@ onBeforeUnmount(() => {
); );
color: var(--color-primary-700); color: var(--color-primary-700);
border-radius: var(--radius) var(--radius) 0 0; border-radius: var(--radius) var(--radius) 0 0;
font-weight: 700;
font-size: 1.1rem; font-size: 1.1rem;
color: var(--color-dark-primary-800); color: var(--color-dark-primary-800);
// cursor: pointer; // cursor: pointer;

View File

@ -0,0 +1,371 @@
<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>

View File

@ -0,0 +1,394 @@
<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>

View File

@ -43,7 +43,8 @@ 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("majles.tavasi.ir", "jedit.tavasi.ir"); base_url = base_url.replace("jedit.tavasi.ir", "majles.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}}";
@ -55,7 +56,7 @@ const setDataEditor = async () => {
node = { node = {
isOpen: false, isOpen: false,
id: item.section_mom_id, id: item.section_mom_id,
title: "قانون مقدم : " + 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: "«منبع»",
@ -90,7 +91,7 @@ const setDataEditor = async () => {
node = { node = {
isOpen: false, isOpen: false,
id: item.section_mom_id, id: item.section_mom_id,
title: "قانون موخر : " + 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: "«منبع»",