Projects (GanjooRazor -> DiwanRazor, GanjoorService.sln -> DiwanService.sln), files, folders, classes, namespaces, settings, API routes (/api/diwan) and DB tables (Diwan*). External addresses (ganjoor.net, github.com/ganjoor) unchanged. Migrations renamed consistently (no pending model changes); requires a fresh database. Upstream RUNNING_LOCALLY/SEMANTIC_SEARCH docs archived unmodified under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
428 lines
18 KiB
Plaintext
428 lines
18 KiB
Plaintext
@page
|
||
@model DiwanRazor.Areas.Admin.Pages.EditQuotedModel
|
||
@using DNTPersianUtils.Core
|
||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||
@{
|
||
Layout = "_AdminLayout";
|
||
ViewData["Title"] = "پیشنهاد مشق شعر";
|
||
}
|
||
|
||
<div class="up-page-header">
|
||
<h1>@ViewData["Title"]</h1>
|
||
</div>
|
||
|
||
@if (!string.IsNullOrEmpty(Model.LastMessage))
|
||
{
|
||
<div class="up-alert up-alert--info">@Html.Raw(Model.LastMessage)</div>
|
||
}
|
||
|
||
@if (Model.DisplayAll)
|
||
{
|
||
<script>
|
||
async function deleteUnpublished(id) {
|
||
var ok = await upConfirm('آیا از حذف این مورد منتشر نشده اطمینان دارید؟');
|
||
if (!ok) return;
|
||
|
||
$.ajax({
|
||
type: "DELETE",
|
||
url: '',
|
||
data: {
|
||
id: id
|
||
},
|
||
error: function (e) {
|
||
upToast(e.responseText || String(e), 'error');
|
||
},
|
||
success: function () {
|
||
|
||
var elem = document.getElementById('tr-' + id);
|
||
elem.parentNode.removeChild(elem);
|
||
},
|
||
});
|
||
}
|
||
|
||
</script>
|
||
<div class="up-page-header">
|
||
<h2>همهٔ مشقهای منتشر نشده</h2>
|
||
</div>
|
||
@if (Model.AllPoemQuoteds != null && Model.AllPoemQuoteds.Length > 0)
|
||
{
|
||
<table>
|
||
<tr>
|
||
<td>#</td>
|
||
<td>شاعر</td>
|
||
<td>۱</td>
|
||
<td>۲</td>
|
||
<td>۱</td>
|
||
<td>۲</td>
|
||
<td>حذف</td>
|
||
</tr>
|
||
@foreach (var q in Model.AllPoemQuoteds)
|
||
{
|
||
<tr id="tr-@q.Id">
|
||
<td><a href="/Admin/EditQuoted/?p=@q.PoemId&id=@q.Id">@q.PoemId-@q.RelatedPoemId</a> </td>
|
||
<td>@q.CachedRelatedPoemPoetName</td>
|
||
<td>
|
||
@if (q.CoupletVerse1ShouldBeEmphasized)
|
||
{
|
||
<span class="red-color">@q.CoupletVerse1</span>
|
||
}
|
||
else
|
||
{
|
||
@q.CoupletVerse1
|
||
}
|
||
</td>
|
||
<td>
|
||
@if (q.CoupletVerse2ShouldBeEmphasized)
|
||
{
|
||
<span class="red-color">@q.CoupletVerse2</span>
|
||
}
|
||
else
|
||
{
|
||
@q.CoupletVerse2
|
||
}
|
||
</td>
|
||
<td>
|
||
@if (q.RelatedCoupletVerse1ShouldBeEmphasized)
|
||
{
|
||
<span class="red-color">@q.RelatedCoupletVerse1</span>
|
||
}
|
||
else
|
||
{
|
||
@q.RelatedCoupletVerse1
|
||
}
|
||
</td>
|
||
<td>
|
||
@if (q.RelatedCoupletVerse2ShouldBeEmphasized)
|
||
{
|
||
<span class="red-color">@q.RelatedCoupletVerse2</span>
|
||
}
|
||
else
|
||
{
|
||
@q.RelatedCoupletVerse2
|
||
}
|
||
</td>
|
||
<td><a role="button" onclick="deleteUnpublished('@q.Id')" class="up-icon-btn" title="حذف" aria-label="حذف این مورد">🗑</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="7">
|
||
<hr />
|
||
</td>
|
||
</tr>
|
||
}
|
||
</table>
|
||
}
|
||
else
|
||
{
|
||
<partial name="_EmptyState" model="@("موردی منتشرنشده یافت نشد.")" />
|
||
}
|
||
return;
|
||
}
|
||
<p>
|
||
<a href="?all=true" class="up-btn up-btn--ghost">📚 همهٔ مشقهای منتشر نشده</a>
|
||
</p>
|
||
|
||
|
||
@if (Model.DiwanQuotedPoem != null && Model.Couplets != null)
|
||
{
|
||
<script>
|
||
|
||
function selectDiwanPage() {
|
||
document.getElementById('display-frame').style.display = 'none';
|
||
document.getElementById('select-poem').style.display = 'block';
|
||
document.getElementById('finalize-select').style.display = 'block';
|
||
}
|
||
|
||
function finalizeSelectPage() {
|
||
|
||
document.getElementById('display-frame').style.display = 'block';
|
||
document.getElementById('select-poem').style.display = 'none';
|
||
document.getElementById('finalize-select').style.display = 'none';
|
||
|
||
const currentUrl = document.getElementById('select-poem').contentWindow.location.href;
|
||
|
||
var url = currentUrl.substring(currentUrl.indexOf('/', currentUrl.indexOf('//') + 2));
|
||
|
||
fetch('@(DiwanRazor.APIRoot.InternetUrl)/api/diwan/page?url=' + url)
|
||
.then((response) => response.json())
|
||
.then((json) => {
|
||
upToast(String(json.poem.id));
|
||
document.getElementById('DiwanQuotedPoem_RelatedPoemId').value = json.poem.id;
|
||
document.getElementById('DiwanQuotedPoem_RelatedPoetId').value = json.poem.category.poet.id;
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemPoetName').value = json.poem.category.poet.nickname;
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemPoetDeathYearInLHijri').value = json.poem.category.poet.deathYearInLHijri.toString();
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemPoetUrl').value = json.poem.category.poet.fullUrl;
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemPoetImage').value = json.poem.category.poet.imageUrl;
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemFullTitle').value = json.poem.fullTitle;
|
||
document.getElementById('DiwanQuotedPoem_CachedRelatedPoemFullUrl').value = json.poem.fullUrl;
|
||
|
||
var coupletIndices = [];
|
||
var coupletTexts = [];
|
||
|
||
for (var i = 0; i < json.poem.verses.length; i++) {
|
||
var verse = json.poem.verses[i];
|
||
if (coupletIndices.indexOf(verse.coupletIndex) != -1) {
|
||
coupletTexts[coupletIndices.indexOf(verse.coupletIndex)] += ' - ';
|
||
coupletTexts[coupletIndices.indexOf(verse.coupletIndex)] += verse.text;
|
||
}
|
||
else {
|
||
coupletIndices.push(verse.coupletIndex);
|
||
coupletTexts.push(verse.text);
|
||
}
|
||
}
|
||
|
||
var x = document.getElementById("DiwanQuotedPoem_RelatedCoupletIndex");
|
||
x.length = 0;
|
||
for (var i = 0; i < coupletIndices.length; i++) {
|
||
var option = document.createElement("option");
|
||
option.text = coupletTexts[i];
|
||
option.value = coupletIndices[i];
|
||
x.add(option);
|
||
}
|
||
|
||
x.value = coupletIndices[0];
|
||
|
||
|
||
});
|
||
|
||
}
|
||
|
||
async function deleteThisOne(id) {
|
||
var ok = await upConfirm('آیا از حذف این مورد اطمینان دارید؟');
|
||
if (!ok) return;
|
||
|
||
$.ajax({
|
||
type: "DELETE",
|
||
url: '',
|
||
data: {
|
||
id: id
|
||
},
|
||
error: function (e) {
|
||
upToast(e.responseText || String(e), 'error');
|
||
},
|
||
success: function () {
|
||
upToast('انجام شد.');
|
||
location.reload(true);
|
||
},
|
||
});
|
||
}
|
||
|
||
|
||
async function reverseQuote(id) {
|
||
var ok = await upConfirm('آیا از درج معکوس این مورد اطمینان دارید؟');
|
||
if (!ok) return;
|
||
|
||
$.ajax({
|
||
type: "POST",
|
||
url: '?handler=GenerateReverse',
|
||
data: {
|
||
id: id
|
||
},
|
||
error: function (e) {
|
||
upToast(e.responseText || String(e), 'error');
|
||
},
|
||
success: function (e) {
|
||
upToast('انجام شد.');
|
||
location.href = e;
|
||
},
|
||
});
|
||
}
|
||
|
||
</script>
|
||
<div class="up-card">
|
||
<form method="post" class="up-form">
|
||
@Html.AntiForgeryToken()
|
||
<p>
|
||
بیت مرجع از <a href="/?p=@Model.DiwanQuotedPoem.PoemId">شعر</a>:
|
||
<input type="hidden" asp-for="DiwanQuotedPoem.Id" />
|
||
<input type="hidden" asp-for="DiwanQuotedPoem.PoemId" />
|
||
<input type="hidden" asp-for="DiwanQuotedPoem.PoetId" />
|
||
</p>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_CoupletIndex">بیت</label>
|
||
<select asp-for="DiwanQuotedPoem.CoupletIndex">
|
||
@foreach (var item in Model.Couplets)
|
||
{
|
||
<option value="@item.Item1">@($"{(item.Item1 + 1).ToPersianNumbers()} - {item.Item2}")</option>
|
||
}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.CoupletVerse1ShouldBeEmphasized" />
|
||
<label for="DiwanQuotedPoem_CoupletVerse1ShouldBeEmphasized">مصرع اول مهم است</label>
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.CoupletVerse2ShouldBeEmphasized" />
|
||
<label for="DiwanQuotedPoem_CoupletVerse2ShouldBeEmphasized">مصرع دوم مهم است</label>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_PoetId">شاعر مرجع</label>
|
||
<input asp-for="DiwanQuotedPoem.PoetId" />
|
||
</div>
|
||
|
||
<div class="up-btn-group">
|
||
<a onclick="finalizeSelectPage()" class="up-btn up-btn--ghost" role="button" id="finalize-select" style="display:none">انتخاب کردم</a>
|
||
<a onclick="selectDiwanPage()" class="up-btn up-btn--ghost" role="button" id="display-frame">🔎 گزینش شعر مرتبط</a>
|
||
</div>
|
||
<iframe id="select-poem" src="/" height="600" style="display:none;width:100%;margin:auto"></iframe>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_RelatedPoemId">شناسهٔ شعر مرتبط</label>
|
||
<input asp-for="DiwanQuotedPoem.RelatedPoemId" />
|
||
</div>
|
||
@if (Model.DiwanQuotedPoem.RelatedPoemId != null)
|
||
{
|
||
<p><a href="/?p=@Model.DiwanQuotedPoem.RelatedPoemId">🔗 مشاهدهٔ شعر مرتبط</a></p>
|
||
}
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_RelatedCoupletIndex">بیت مرتبط</label>
|
||
<select asp-for="DiwanQuotedPoem.RelatedCoupletIndex">
|
||
@foreach (var item in Model.RelatedCouplets)
|
||
{
|
||
<option value="@item.Item1">@($"{(item.Item1 + 1).ToPersianNumbers()} - {item.Item2}")</option>
|
||
}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_RelatedCoupletVerse1">مصرع اول مرتبط (خارج از دیوان)</label>
|
||
<input asp-for="DiwanQuotedPoem.RelatedCoupletVerse1" size="65" />
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.RelatedCoupletVerse1ShouldBeEmphasized" />
|
||
<label for="DiwanQuotedPoem_RelatedCoupletVerse1ShouldBeEmphasized">مصرع اول مهم است</label>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_RelatedCoupletVerse2">مصرع دوم مرتبط (خارج از دیوان)</label>
|
||
<input asp-for="DiwanQuotedPoem.RelatedCoupletVerse2" size="65" />
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.RelatedCoupletVerse2ShouldBeEmphasized" />
|
||
<label for="DiwanQuotedPoem_RelatedCoupletVerse2ShouldBeEmphasized">مصرع دوم مهم است</label>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_SortOrder">ترتیب</label>
|
||
<input asp-for="DiwanQuotedPoem.SortOrder" />
|
||
</div>
|
||
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.IsPriorToRelated" />
|
||
<label for="DiwanQuotedPoem_IsPriorToRelated">این شعر قدیمیتر از شعر مرتبط است</label>
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.ChosenForMainList" />
|
||
<label for="DiwanQuotedPoem_ChosenForMainList">نمایش در فهرست اصلی</label>
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.IndirectQuotation" />
|
||
<label for="DiwanQuotedPoem_IndirectQuotation">مستقیماً ارتباط ندارد</label>
|
||
</div>
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.ClaimedByBothPoets" />
|
||
<label for="DiwanQuotedPoem_ClaimedByBothPoets">منتسب به هر دو شاعر</label>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_RelatedPoetId">شاعر</label>
|
||
<input asp-for="DiwanQuotedPoem.RelatedPoetId" />
|
||
</div>
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemPoetName">نام شاعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemPoetName" />
|
||
</div>
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemPoetDeathYearInLHijri">سالمرگ شاعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemPoetDeathYearInLHijri" />
|
||
</div>
|
||
<div class="up-field up-field--ltr">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemPoetUrl">نشانی صفحهٔ شاعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemPoetUrl" size="65" />
|
||
</div>
|
||
<div class="up-field up-field--ltr">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemPoetImage">تصویر شاعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemPoetImage" size="65" />
|
||
</div>
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemFullTitle">عنوان شعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemFullTitle" size="65" />
|
||
</div>
|
||
<div class="up-field up-field--ltr">
|
||
<label for="DiwanQuotedPoem_CachedRelatedPoemFullUrl">نشانی شعر</label>
|
||
<input asp-for="DiwanQuotedPoem.CachedRelatedPoemFullUrl" size="65" />
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_Note"><span class="up-field-icon" aria-hidden="true">🗒️</span> یادداشت</label>
|
||
<textarea asp-for="DiwanQuotedPoem.Note" rows="4" cols="80" class="editor"></textarea>
|
||
</div>
|
||
|
||
<div class="up-check-row">
|
||
<input asp-for="DiwanQuotedPoem.Published" />
|
||
<label for="DiwanQuotedPoem_Published">منتشر شده</label>
|
||
</div>
|
||
|
||
<div class="up-field">
|
||
<label for="DiwanQuotedPoem_SamePoemsQuotedCount">تعداد همسانها</label>
|
||
<input asp-for="DiwanQuotedPoem.SamePoemsQuotedCount" />
|
||
</div>
|
||
|
||
<div class="up-form-actions">
|
||
<input type="submit" value="ذخیره" class="up-btn up-btn--success" />
|
||
</div>
|
||
|
||
<hr />
|
||
|
||
<div class="up-btn-group">
|
||
@if (Model.ReverseId != null)
|
||
{
|
||
<a href="/Admin/EditQuoted/?p=@Model.DiwanQuotedPoem.RelatedPoemId&id=@Model.ReverseId" class="up-btn up-btn--ghost">🔁 نمایش معکوس</a>
|
||
}
|
||
else
|
||
{
|
||
<a role="button" onclick="reverseQuote('@Model.DiwanQuotedPoem.Id')" class="up-btn up-btn--ghost" title="درج معکوس">🔁 درج معکوس</a>
|
||
}
|
||
<a role="button" onclick="deleteThisOne('@Model.DiwanQuotedPoem.Id')" class="up-btn up-btn--danger" title="حذف">🗑 حذف</a>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
|
||
<div class="up-page-header">
|
||
<h2>همهٔ مشقهای شعر</h2>
|
||
</div>
|
||
@if (Model.AllPoemQuoteds != null && Model.AllPoemQuoteds.Length > 0)
|
||
{
|
||
<table>
|
||
<tr>
|
||
<td>#</td>
|
||
<td>شاعر</td>
|
||
<td>۱</td>
|
||
<td>۲</td>
|
||
<td>۱</td>
|
||
<td>۲</td>
|
||
<td>منتشر شده</td>
|
||
</tr>
|
||
@foreach (var q in Model.AllPoemQuoteds)
|
||
{
|
||
<tr>
|
||
<td><a href="/Admin/EditQuoted/?p=@q.PoemId&id=@q.Id">#</a> </td>
|
||
<td>@q.CachedRelatedPoemPoetName</td>
|
||
<td>@q.CoupletVerse1</td>
|
||
<td>@q.CoupletVerse2</td>
|
||
<td>@q.RelatedCoupletVerse1</td>
|
||
<td>@q.RelatedCoupletVerse2</td>
|
||
<td>@q.Published</td>
|
||
</tr>
|
||
}
|
||
</table>
|
||
}
|
||
else
|
||
{
|
||
<partial name="_EmptyState" model="@("مشقی برای این شعر ثبت نشده است.")" />
|
||
}
|
||
}
|