mprove UI/UX of the User Area

#496
This commit is contained in:
Hamid Reza Mohammadi 2026-08-05 16:55:42 +03:30
parent 2fee534f11
commit e65652e4dc
7 changed files with 415 additions and 689 deletions

View File

@ -1,201 +1,119 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.AwaitingCommentsModel
@using DNTPersianUtils.Core
@{
Layout = "_UserPanelLayout";
ViewData["Title"] = "حاشیه‌های در انتظار تأیید";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
string color = "gray";
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
else
{
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
<script>
function deleteAwaitingComment(commentId) {
if (!confirm('آیا از حذف این حاشیه اطمینان دارید؟'))
return;
var url = '?handler=Comment';
async function deleteAwaitingComment(commentId) {
var ok = await upConfirm('آیا از حذف این حاشیه اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "DELETE",
url: url,
data: {
id: commentId
},
error: function () {
alert('خطا رخ داد.');
url: '?handler=Comment',
data: { id: commentId },
error: function (e) {
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
var commentBlockId = '#comment-' + commentId;
$(commentBlockId).remove();
$('#comment-' + commentId).remove();
upToast('حاشیه حذف شد.', 'success');
},
});
}
function publishAwaitingComment(commentId) {
if (!confirm('آیا از انتشار این حاشیه اطمینان دارید؟'))
return;
var url = '?handler=Approve';
async function publishAwaitingComment(commentId) {
var ok = await upConfirm('آیا از انتشار این حاشیه اطمینان دارید؟', { danger: false, okText: 'بله، منتشر شود' });
if (!ok) return;
$.ajax({
type: "PUT",
url: url,
data: {
id: commentId
},
error: function () {
alert('خطا رخ داد.');
url: '?handler=Approve',
data: { id: commentId },
error: function (e) {
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
var commentBlockId = '#comment-' + commentId;
$(commentBlockId).remove();
$('#comment-' + commentId).remove();
upToast('حاشیه منتشر شد.', 'success');
},
});
}
function switchOption(start) {
if(start == false){
document.getElementById('switch-tracking-button').style.visibility = 'hidden';
document.getElementById('processing').innerHTML = 'در حال پردازش ...';
$.ajax({
type: "POST",
url: '?handler=StopKeeping',
error: function() {
alert('خطا رخ داد.');
location.reload();
},
success: function () {
location.reload();
},
});
return;
}
document.getElementById('switch-tracking-button').style.visibility = 'hidden';
document.getElementById('processing').innerHTML = 'در حال پردازش ...';
$.ajax({
type: "POST",
url: '?handler=StartKeeping',
error: function() {
alert('خطا رخ داد.');
url: start ? '?handler=StartKeeping' : '?handler=StopKeeping',
error: function () {
upToast('خطا رخ داد.', 'error');
location.reload();
},
success: function () {
location.reload();
location.reload();
},
});
});
}
</script>
<div class="related-images-frame">
<partial name="_Pagination" model="Model.PaginationLinks" />
<div class="up-card">
@if (Model.KeepFirstTimeUsersComments)
{
<p style="text-align:center; color: green">
نگه داشتن حاشیه‌های حاشیه‌گذاران بدون سابقه فعال است.
</p>
<p>
<a role="button" onclick="switchOption(false)" id="switch-tracking-button" class="pagebutton">غیرفعال کردن</a>
</p>
<p id="processing">
</p>
<div class="up-alert up-alert--success up-text-center">نگه داشتن حاشیه‌های حاشیه‌گذاران بدون سابقه فعال است.</div>
<div class="up-form-actions" style="justify-content:center;">
<a role="button" onclick="switchOption(false)" id="switch-tracking-button" class="up-btn up-btn--ghost">غیرفعال کردن</a>
</div>
}
else
{
<p>
نگه داشتن حاشیه‌های حاشیه‌گذاران بدون سابقه غیرفعال است.
</p>
<p>
<a role="button" onclick="switchOption(true)" id="switch-tracking-button" class="pagebutton">فعال کردن</a>
</p>
<p id="processing">
</p>
<p class="up-text-center">نگه داشتن حاشیه‌های حاشیه‌گذاران بدون سابقه غیرفعال است.</p>
<div class="up-form-actions" style="justify-content:center;">
<a role="button" onclick="switchOption(true)" id="switch-tracking-button" class="up-btn up-btn--success">فعال کردن</a>
</div>
}
<p id="processing" class="up-text-center"></p>
</div>
@if (Model.Comments.Count == 0)
{
<p>
موردی وجود ندارد.
</p>
<partial name="_EmptyState" model="@("موردی وجود ندارد.")" />
}
@foreach (var comment in Model.Comments)
else
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="comment-@comment.Id">
<blockquote>
<div id="comment-text-@comment.Id">
@Html.Raw(comment.HtmlComment)
<div class="up-list">
@foreach (var comment in Model.Comments)
{
<div class="up-list-item" id="comment-@comment.Id">
<div id="comment-text-@comment.Id">
@Html.Raw(comment.HtmlComment)
</div>
<div class="up-list-item__meta">
<a href="/Admin/ExamineUser?id=@comment.UserId">@comment.AuthorName</a> در @comment.CommentDate.ToFriendlyPersianDateTextify() دربارهٔ <a href="@comment.Poem.UrlSlug#comment-@comment.Id">@comment.Poem.Title</a>
</div>
<div class="up-list-item__actions">
<a role="button" onclick="deleteAwaitingComment(@comment.Id)" class="up-icon-btn" title="حذف حاشیه" aria-label="حذف این حاشیه"><i class="noindent-info-button delete-icon"></i></a>
<a role="button" onclick="publishAwaitingComment(@comment.Id)" class="up-icon-btn" title="انتشار حاشیه" aria-label="انتشار این حاشیه"><i class="noindent-info-button done-icon"></i></a>
</div>
</div>
<p>
@comment.AuthorName <small>در @comment.CommentDate.ToFriendlyPersianDateTextify()</small> دربارهٔ <a href="@comment.Poem.UrlSlug#comment-@comment.Id">@comment.Poem.Title</a>
</p>
<p>
<a href="/Admin/ExamineUser?id=@comment.UserId">#</a>
</p>
</blockquote>
<p>
<a role="button" onclick="deleteAwaitingComment(@comment.Id)" class="actionlink" title="حذف حاشیه"><i class="noindent-info-button delete-icon"></i></a>
<a role="button" onclick="publishAwaitingComment(@comment.Id)" class="actionlink" title="انتشار حاشیه"><i class="noindent-info-button done-icon"></i></a>
</p>
}
</div>
<hr />
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
<partial name="_Pagination" model="Model.PaginationLinks" />
}

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.FAQItemsModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
@ -6,104 +6,99 @@
ViewData["Title"] = "پرسش‌های متداول";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (!string.IsNullOrEmpty(Model.LastMessage))
{
<p>
@Model.LastMessage
</p>
<div class="up-alert up-alert--info">@Model.LastMessage</div>
}
else
{
<script>
function editCategory(){
function editCategory() {
location.href = '/User/FAQCatEdit?id=' + String(document.getElementById('cat').value);
}
function newItem(){
function newItem() {
location.href = '/User/FAQItemEdit?catId=' + String(document.getElementById('cat').value);
}
function deleteCategory() {
function faqItemRow(item) {
return '<div class="up-list-item">' +
'<a href="/User/FAQItemEdit?id=' + String(item.id) + '">' + item.question + '</a>' +
'<div class="up-list-item__actions">' +
'<a role="button" onclick="deleteItem(' + String(item.id) + ')" class="up-icon-btn" title="حذف" aria-label="حذف این پرسش"><i class="noindent-info-button delete-icon"></i></a>' +
'</div>' +
'</div>';
}
async function deleteCategory() {
var sel = document.getElementById('cat');
var text= sel.options[sel.selectedIndex].text;
var text = sel.options[sel.selectedIndex].text;
if (!confirm('آیا از حذف '+text+' اطمینان دارید؟'))
return;
var ok = await upConfirm('آیا از حذف ' + text + ' اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "DELETE",
url: '',
data: {
id: sel.value
},
data: { id: sel.value },
error: function (e) {
if (e.responseText == null)
alert(e);
else
alert(e.responseText);
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
location.reload();
location.reload();
},
});
}
function deleteItem(id) {
if (!confirm('آیا از حذف این پرسش اطمینان دارید؟'))
return;
async function deleteItem(id) {
var ok = await upConfirm('آیا از حذف این پرسش اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "DELETE",
url: '?Handler=Item',
data: {
id: id
},
data: { id: id },
error: function (e) {
if (e.responseText == null)
alert(e);
else
alert(e.responseText);
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
location.reload();
location.reload();
},
});
}
function onSelectedCatChanged(){
function onSelectedCatChanged() {
var sel = document.getElementById('cat');
if(sel.selectedIndex >= 0){
if (sel.selectedIndex >= 0) {
document.getElementById('catItems').innerHTML = 'در حال بارگذاری ...';
$.ajax({
type: "GET",
url: '?Handler=CategoryItems',
data: {
id: sel.value
},
error: function (e) {
document.getElementById('catItems').innerHTML = '';
if (e.responseText == null)
alert(e);
else
alert(e.responseText);
},
success: function (items) {
var s = '';
for(var i=0; i<items.length; i++){
s += ('<p><a href="/User/FAQItemEdit?id='+String(items[i].id)+'">' + '<p>' + items[i].question + '</a></p>');
s += ('<a role="button" onclick="deleteItem('+String(items[i].id)+')" class="actionlink" title="حذف"><i class="noindent-info-button delete-icon"></i></a>');
}
document.getElementById('catItems').innerHTML = s;
},
});
type: "GET",
url: '?Handler=CategoryItems',
data: { id: sel.value },
error: function (e) {
document.getElementById('catItems').innerHTML = '';
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function (items) {
var s = '';
for (var i = 0; i < items.length; i++) {
s += faqItemRow(items[i]);
}
document.getElementById('catItems').innerHTML = s || '<p class="up-text-muted">پرسشی در این دسته نیست.</p>';
},
});
}
}
</script>
<table>
<tr>
<td>دسته‌بندی پرسش‌ها:</td>
<td>
<select name="cat" id="cat" onchange="onSelectedCatChanged()">
<div class="up-card">
<div class="up-field">
<label for="cat">دسته‌بندی پرسش‌ها</label>
<div class="up-form-actions">
<select name="cat" id="cat" onchange="onSelectedCatChanged()" style="flex:1;">
@foreach (var category in Model.Categories)
{
@if (category.Id == Model.CatId)
@ -116,31 +111,32 @@ else
}
}
</select>
<a role="button" onclick="editCategory()" class="actionlink" title="ویرایش"><i class="noindent-info-button edit-poem-button"></i></a>
<a role="button" onclick="deleteCategory()" class="actionlink" title="حذف"><i class="noindent-info-button delete-icon"></i></a>
</td>
</tr>
<tr>
<td colspan="2">
<a role="button" href="/User/FAQCatEdit" class="pagebutton" title="جدید">دستهٔ جدید</a>
</td>
</tr>
</table>
<a role="button" onclick="editCategory()" class="up-icon-btn" title="ویرایش" aria-label="ویرایش دسته"><i class="noindent-info-button edit-poem-button"></i></a>
<a role="button" onclick="deleteCategory()" class="up-icon-btn" title="حذف" aria-label="حذف دسته"><i class="noindent-info-button delete-icon"></i></a>
</div>
</div>
<a role="button" href="/User/FAQCatEdit" class="up-btn up-btn--ghost" title="جدید">دستهٔ جدید</a>
</div>
<h2>پرسش‌های دستهٔ جاری</h2>
<p>
<a role="button" onclick="newItem()" class="pagebutton">پرسش جدید</a>
</p>
<div id="catItems">
<div class="up-page-header">
<h2>پرسش‌های دستهٔ جاری</h2>
</div>
<div class="up-form-actions" style="margin-bottom:var(--up-space-3);">
<a role="button" onclick="newItem()" class="up-btn up-btn--success">پرسش جدید</a>
</div>
<div id="catItems" class="up-list">
@if (Model.CategoryItems != null)
{
@foreach (var item in Model.CategoryItems)
{
<p><a href="/User/FAQItemEdit?id=@item.Id">@item.Question</a></p>
<a role="button" onclick="deleteItem(@item.Id)" class="actionlink" title="حذف"><i class="noindent-info-button delete-icon"></i></a>
<div class="up-list-item">
<a href="/User/FAQItemEdit?id=@item.Id">@item.Question</a>
<div class="up-list-item__actions">
<a role="button" onclick="deleteItem(@item.Id)" class="up-icon-btn" title="حذف" aria-label="حذف این پرسش"><i class="noindent-info-button delete-icon"></i></a>
</div>
</div>
}
}
</div>
}

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.FinalizeImagesModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
@ -6,50 +6,49 @@
ViewData["Title"] = "نهایی‌سازی تصاویر پیشنهادی";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
@if (Model.MainImage != null)
@if (Model.MainImage == null)
{
<table style="width:100%" class="noborder">
<tr>
<td colspan="2">
<a href="@Model.MainImage.GanjoorUrl" target="_blank">@Model.MainImage.GanjoorTitle</a>
</td>
</tr>
<tr>
<td>
<img src="@Model.MainImage.ExternalNormalSizeImageUrl" />
</td>
<td>
<partial name="_EmptyState" model="@("تصویری برای نهایی‌سازی وجود ندارد.")" />
}
else
{
<div class="up-card">
<p><a href="@Model.MainImage.GanjoorUrl" target="_blank">@Model.MainImage.GanjoorTitle</a></p>
<div style="display:flex;gap:var(--up-space-3);flex-wrap:wrap;">
<div>
<p class="up-hint">تصویر پیشنهادی</p>
<img src="@Model.MainImage.ExternalNormalSizeImageUrl" style="max-width:100%;" />
</div>
@if (Model.PreviouslyLinkedImage != null)
{
<img src="@Model.PreviouslyLinkedImage.ExternalNormalSizeImageUrl" />
<div>
<p class="up-hint">تصویر فعلی</p>
<img src="@Model.PreviouslyLinkedImage.ExternalNormalSizeImageUrl" style="max-width:100%;" />
</div>
}
</td>
</tr>
<tr>
<td colspan="2">
<form method="post">
<input type="hidden" asp-for="ImageLinkFinalizeModel.Id" />
</div>
<form method="post" class="up-form">
<input type="hidden" asp-for="ImageLinkFinalizeModel.Id" />
<div class="up-field">
<label asp-for="ImageLinkFinalizeModel.DisplayOnPage"></label>
<input asp-for="ImageLinkFinalizeModel.DisplayOnPage" />
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تأیید</button>
</form>
</td>
</tr>
<tr>
<td>
تعداد کل:
</td>
<td>
@Model.TotalCount
</td>
</tr>
</table>
}
</div>
<div class="up-form-actions">
<button type="submit" name="approve" id="approve" class="up-btn up-btn--success">تأیید</button>
</div>
</form>
<p class="up-hint">تعداد کل: @Model.TotalCount</p>
</div>
}

View File

@ -1,112 +1,83 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.ReportedCommentsModel
@using DNTPersianUtils.Core
@{
Layout = "_UserPanelLayout";
ViewData["Title"] = "حاشیه‌های گزارش شده";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
string color = "gray";
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
else
{
<script>
function moderateReportedComment(reportId) {
if (!confirm('آیا از حذف این حاشیه اطمینان دارید؟'))
return;
async function moderateReportedComment(reportId) {
var ok = await upConfirm('آیا از حذف این حاشیه اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "POST",
url: '?handler=ModerateComment',
data: {
id: reportId,
data: { id: reportId },
error: function (e) {
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
var commentBlockId = '#report-' + reportId;
$(commentBlockId).remove();
$('#report-' + reportId).remove();
upToast('حاشیه حذف شد.', 'success');
},
});
}
function deleteReport(reportId) {
$.ajax({
type: "DELETE",
url: '?handler=Report',
data: {
id: reportId
data: { id: reportId },
error: function (e) {
upToast(e.responseText || 'خطا رخ داد.', 'error');
},
success: function () {
var commentBlockId = '#report-' + reportId;
$(commentBlockId).remove();
$('#report-' + reportId).remove();
upToast('گزارش حذف شد.', 'success');
},
});
}
</script>
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
<partial name="_Pagination" model="Model.PaginationLinks" />
@foreach (var report in Model.Reports)
@if (Model.Reports.Count == 0)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="report-@report.Id">
<p style="color:red">
@report.ReasonCode
</p>
<hr />
<p style="color:red">
@report.ReasonText
</p>
<hr />
<blockquote>
@Html.Raw(report.Comment.HtmlComment)
<p>
@report.Comment.AuthorName <small>در @report.Comment.CommentDate.ToFriendlyPersianDateTextify()</small> دربارهٔ <a href="@report.Comment.Poem.UrlSlug#comment-@report.Comment.Id">@report.Comment.Poem.Title</a>
</p>
</blockquote>
<a role="button" onclick="moderateReportedComment(@report.Id)" class="actionlink" style="color:green" title="تأیید و حذف حاشیه">✓ درست می‌گوید</a>
&nbsp;&nbsp;&nbsp;
<a role="button" onclick="deleteReport(@report.Id, @report.Comment.Id)" class="actionlink" style="color:red" title="حذف گزارش">گزارش نابجا ❌</a>
</div>
<hr />
<partial name="_EmptyState" model="@("گزارش رسیدگی‌نشده‌ای وجود ندارد.")" />
}
else
{
<div class="up-list">
@foreach (var report in Model.Reports)
{
<div class="up-list-item" id="report-@report.Id">
<span class="up-badge up-badge--danger">@report.ReasonCode</span>
<p>@report.ReasonText</p>
<blockquote>
@Html.Raw(report.Comment.HtmlComment)
<div class="up-list-item__meta">
@report.Comment.AuthorName در @report.Comment.CommentDate.ToFriendlyPersianDateTextify() دربارهٔ <a href="@report.Comment.Poem.UrlSlug#comment-@report.Comment.Id">@report.Comment.Poem.Title</a>
</div>
</blockquote>
<div class="up-list-item__actions">
<a role="button" onclick="moderateReportedComment(@report.Id)" class="up-btn up-btn--danger up-btn--sm" title="تأیید و حذف حاشیه">✓ درست می‌گوید</a>
<a role="button" onclick="deleteReport(@report.Id)" class="up-btn up-btn--ghost up-btn--sm" title="حذف گزارش">گزارش نابجا ❌</a>
</div>
</div>
}
</div>
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
}
</p>
}
<partial name="_Pagination" model="Model.PaginationLinks" />
}

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.ReviewSongsModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using DNTPersianUtils.Core
@ -7,266 +7,187 @@
ViewData["Title"] = "آهنگ‌های پیشنهادی";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
else if (@Model.PoemMusicTrackViewModel == null)
{
<p>پیشنهادی وجود ندارد.</p>
<partial name="_EmptyState" model="@("پیشنهادی وجود ندارد.")" />
}
else if (@Model.Poem == null)
{
<p>شعر مرتبط یافت نشد!</p>
<div class="up-alert up-alert--warning">شعر مرتبط یافت نشد!</div>
}
else
{
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">شعر: </span>
</td>
<td>
<div class="up-card">
<form method="post" class="up-form">
<div class="up-field">
<label>شعر</label>
<div>
<a href="@Html.Raw(Model.Poem.FullUrl)" target="_blank">@Model.Poem.FullTitle</a>
<input type="hidden" asp-for="PoemMusicTrackViewModel.Id" />
<input type="hidden" asp-for="PoemMusicTrackViewModel.PoemId" />
<input type="hidden" asp-for="PoemMusicTrackViewModel.GolhaTrackId" />
<input type="hidden" asp-for="PoemMusicTrackViewModel.TrackType" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">پیشنهاد دهنده: </span>
</td>
<td>
<a href="/hashieha/?userid=@Model.PoemMusicTrackViewModel.SuggestedById" target="_blank">@Model.PoemMusicTrackViewModel.SuggestedByNickName</a>
</td>
</tr>
</div>
</div>
<div class="up-field">
<label>پیشنهاد دهنده</label>
<div><a href="/hashieha/?userid=@Model.PoemMusicTrackViewModel.SuggestedById" target="_blank">@Model.PoemMusicTrackViewModel.SuggestedByNickName</a></div>
</div>
@if (Model.UserSongSuggestionsHistory != null && (Model.UserSongSuggestionsHistory.Approved + Model.UserSongSuggestionsHistory.Rejected) > 0)
{
<tr>
<td>
@if (Model.UserSongSuggestionsHistory.Approved > 0)
{
<span style="color:green"><strong>@Model.UserSongSuggestionsHistory.Approved.ToPersianNumbers()</strong> پیشنهاد تأیید شده</span>
}
</td>
<td>
@if (Model.UserSongSuggestionsHistory.Rejected > 0)
{
<span style="color:red"><strong>@Model.UserSongSuggestionsHistory.Rejected.ToPersianNumbers()</strong> پیشنهاد رد شده</span>
}
</td>
</tr>
<div class="up-form-actions">
@if (Model.UserSongSuggestionsHistory.Approved > 0)
{
<span class="up-badge up-badge--success">@Model.UserSongSuggestionsHistory.Approved.ToPersianNumbers() پیشنهاد تأیید شده</span>
}
@if (Model.UserSongSuggestionsHistory.Rejected > 0)
{
<span class="up-badge up-badge--danger">@Model.UserSongSuggestionsHistory.Rejected.ToPersianNumbers() پیشنهاد رد شده</span>
}
</div>
}
<tr>
<td colspan="2">
@{
switch (Model.PoemMusicTrackViewModel.TrackType)
{
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Spotify:
<img src="/image/spotify.png" alt="اسپاتیفای" height="32" />
break;
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Golha:
<img src="/image/golha.png" alt="گلها" height="32" />
break;
default:
<img src="/image/beeptunes.png" alt="بیپ‌تونز" height="32" />
break;
}
<div>
@{
switch (Model.PoemMusicTrackViewModel.TrackType)
{
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Spotify:
<img src="/image/spotify.png" alt="اسپاتیفای" height="32" />
break;
case RMuseum.Models.Ganjoor.PoemMusicTrackType.Golha:
<img src="/image/golha.png" alt="گلها" height="32" />
break;
default:
<img src="/image/beeptunes.png" alt="بیپ‌تونز" height="32" />
break;
}
</td>
</tr>
<tr>
<td>
<span class="inputlabel">خواننده: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.ArtistName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.ArtistUrl)">نشانی خواننده:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.ArtistUrl" />
</td>
</tr>
<tr>
<td>
</td>
<td>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آلبوم:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.AlbumName" /><br />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.AlbumUrl)">نشانی آلبوم:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.AlbumUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">آهنگ:</span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.TrackName" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel"><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.TrackUrl)">نشانی آهنگ:</a></span>
</td>
<td>
<input style="width:100%;text-align:left;direction:ltr;" asp-for="PoemMusicTrackViewModel.TrackUrl" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">توضیح: </span>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.Description" /><br />
</td>
</tr>
<tr>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">
@if (Model.EditMode)
{
<text>اصلاح</text>
}
else
{
<text>تأیید</text>
}
</button>
</td>
<td>
<table style="width:100%" class="noborder">
@if (Model.EditMode)
{
<tr>
<td>
<button type="submit" name="delsong" id="delsong" style="width:100%;color:white;background-color:darkred">حذف</button>
</td>
}
</div>
</tr>
<div class="up-field">
<label asp-for="PoemMusicTrackViewModel.ArtistName">خواننده</label>
<input asp-for="PoemMusicTrackViewModel.ArtistName" />
</div>
<div class="up-field up-field--ltr">
<label><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.ArtistUrl)">نشانی خواننده</a></label>
<input asp-for="PoemMusicTrackViewModel.ArtistUrl" />
</div>
}
else
{
<tr>
<td>
<button type="submit" name="reject1" id="reject1" style="width:100%;color:white;background-color:darkred">در آهنگ این شعر خوانده نشده</button>
</td>
<div class="up-field">
<label asp-for="PoemMusicTrackViewModel.AlbumName">آلبوم</label>
<input asp-for="PoemMusicTrackViewModel.AlbumName" />
</div>
<div class="up-field up-field--ltr">
<label><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.AlbumUrl)">نشانی آلبوم</a></label>
<input asp-for="PoemMusicTrackViewModel.AlbumUrl" />
</div>
</tr>
<tr>
<td>
<button type="submit" name="reject2" id="reject2" style="width:100%;color:white;background-color:darkred">لینک یا اطلاعات آهنگ ایراد دارد</button>
</td>
</tr>
<tr>
<td>
<button type="submit" name="reject3" id="reject3" style="width:100%;color:white;background-color:darkred">رد به دلیل دیگر:</button>
</td>
<td>
<input style="width:100%" asp-for="PoemMusicTrackViewModel.RejectionCause" /><br />
</td>
</tr>
<tr>
<td>
<button type="submit" name="next" id="next" style="width:100%;color:white;background-color:orange">بعدی</button>
</td>
</tr>
}
</table>
<div class="up-field">
<label asp-for="PoemMusicTrackViewModel.TrackName">آهنگ</label>
<input asp-for="PoemMusicTrackViewModel.TrackName" />
</div>
<div class="up-field up-field--ltr">
<label><a target="_blank" href="@Html.Raw(Model.PoemMusicTrackViewModel.TrackUrl)">نشانی آهنگ</a></label>
<input asp-for="PoemMusicTrackViewModel.TrackUrl" />
</div>
</td>
</tr>
<tr>
<td>
تعداد کل:
</td>
<td>
@Model.TotalCount
</td>
</tr>
</table>
<div class="up-field">
<label asp-for="PoemMusicTrackViewModel.Description">توضیح</label>
<input asp-for="PoemMusicTrackViewModel.Description" />
</div>
</form>
<div class="up-form-actions">
<button type="submit" name="approve" id="approve" class="up-btn up-btn--success">
@if (Model.EditMode)
{
<text>اصلاح</text>
}
else
{
<text>تأیید</text>
}
</button>
@if (Model.EditMode)
{
<button type="submit" name="delsong" id="delsong" class="up-btn up-btn--danger">حذف</button>
}
else
{
<button type="submit" name="reject1" id="reject1" class="up-btn up-btn--danger">در آهنگ این شعر خوانده نشده</button>
<button type="submit" name="reject2" id="reject2" class="up-btn up-btn--danger">لینک یا اطلاعات آهنگ ایراد دارد</button>
<button type="submit" name="next" id="next" class="up-btn up-btn--ghost">بعدی</button>
}
</div>
@if (!Model.EditMode)
{
<div class="up-field">
<label asp-for="PoemMusicTrackViewModel.RejectionCause">رد به دلیل دیگر</label>
<div class="up-form-actions">
<input asp-for="PoemMusicTrackViewModel.RejectionCause" style="flex:1;" />
<button type="submit" name="reject3" id="reject3" class="up-btn up-btn--danger">رد</button>
</div>
</div>
}
<p class="up-hint">تعداد کل: @Model.TotalCount</p>
</form>
</div>
}
@if (ViewData.ContainsKey("ganjoor-songrevu"))
{
<a class="nav-link text-dark" asp-area="User" asp-page="/AddSong">اضافه کردن آهنگ از منبع دلخواه</a>
<div class="up-form-actions">
<a class="up-btn up-btn--ghost" asp-area="User" asp-page="/AddSong">اضافه کردن آهنگ از منبع دلخواه</a>
</div>
}
<script>
function rebuildMundex() {
if (!confirm('آیا از بازسازی صفحات نمایهٔ موسیقی اطمینان دارید؟'))
return;
var url = '?handler=RebuildMundex';
async function rebuildMundex() {
var ok = await upConfirm('آیا از بازسازی صفحات نمایهٔ موسیقی اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "POST",
url: url,
url: '?handler=RebuildMundex',
error: function () {
alert('خطا رخ داد.')
upToast('خطا رخ داد.', 'error');
},
success: function () {
alert('فرایند بازسازی صفحات نمایهٔ موسیقی شروع شد.')
upToast('فرایند بازسازی صفحات نمایهٔ موسیقی شروع شد.', 'success');
},
});
}
function cleanMundexCache() {
if (!confirm('آیا از حذف کش صفحات موسیقی اطمینان دارید؟'))
return;
var url = '?handler=CleanMundexCache';
async function cleanMundexCache() {
var ok = await upConfirm('آیا از حذف کش صفحات موسیقی اطمینان دارید؟');
if (!ok) return;
$.ajax({
type: "POST",
url: url,
url: '?handler=CleanMundexCache',
error: function () {
alert('خطا رخ داد.')
upToast('خطا رخ داد.', 'error');
},
success: function () {
alert('کش صفخات پاک شد.')
upToast('کش صفحات پاک شد.', 'success');
},
});
}
</script>
<p><a role="button" onclick="rebuildMundex()" class="actionlink" title="بازسازی صفحات نمایهٔ موسیقی">بازسازی صفحات نمایهٔ موسیقی</a></p>
<p><a role="button" onclick="cleanMundexCache()" class="actionlink" title="حذف کش صفحات نمایهٔ موسیقی">حذف کش صفحات نمایهٔ موسیقی</a></p>
<div class="up-form-actions">
<a role="button" onclick="rebuildMundex()" class="up-btn up-btn--ghost" title="بازسازی صفحات نمایهٔ موسیقی">بازسازی صفحات نمایهٔ موسیقی</a>
<a role="button" onclick="cleanMundexCache()" class="up-btn up-btn--ghost" title="حذف کش صفحات نمایهٔ موسیقی">حذف کش صفحات نمایهٔ موسیقی</a>
</div>

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.SuggestedPoetPhotosModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
@ -6,106 +6,61 @@
ViewData["Title"] = "تصاویر پیشنهادی برای تصاویر سخنوران";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
else
{
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">سخنور: </span>
</td>
<td>
<div class="up-card">
<form method="post" class="up-form">
<div class="up-field">
<label>سخنور</label>
<div>
<a href="/photos?p=@Model.Poet.FullUrl.Substring(1)" target="_blank">@Model.Poet.Nickname</a>
<input type="hidden" asp-for="Suggestion.Id" />
<input type="hidden" asp-for="Suggestion.PoetId" />
<input type="hidden" asp-for="Suggestion.SuggestedById" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">پیشنهاد دهنده: </span>
</td>
<td>
<a href="/hashieha/?userid=@Model.Suggestion.SuggestedById" target="_blank">@Model.Suggestion.SuggestedById</a>
</td>
</tr>
</div>
</div>
<tr>
<td colspan="2">
<img src="@Model.Suggestion.ImageUrl" />
</td>
</tr>
<div class="up-field">
<label>پیشنهاد دهنده</label>
<div><a href="/hashieha/?userid=@Model.Suggestion.SuggestedById" target="_blank">@Model.Suggestion.SuggestedById</a></div>
</div>
<tr>
<td>
<span class="inputlabel">عنوان: </span>
</td>
<td>
<input asp-for="Suggestion.Title" />
</td>
</tr>
<img src="@Model.Suggestion.ImageUrl" style="max-width:100%;" />
<tr>
<td>
<span class="inputlabel">توضیحات: </span>
</td>
<td>
<textarea asp-for="Suggestion.Description" class="editor"></textarea>
</td>
</tr>
<tr>
<td>
<span class="inputlabel">ترتیب: </span>
</td>
<td>
<input asp-for="Suggestion.PicOrder" />
</td>
</tr>
<tr>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تأیید</button>
</td>
<td>
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">علت رد: </span>
<input asp-for="Suggestion.RejectionCause" />
</td>
</tr>
<tr>
<td>
<button type="submit" name="reject" id="reject" style="width:100%;color:white;background-color:darkred">رد</button>
</td>
</tr>
<tr>
<td>
<button type="submit" name="next" id="next" style="width:100%;color:white;background-color:orange">بعدی</button>
</td>
</tr>
</table>
<div class="up-field">
<label asp-for="Suggestion.Title">عنوان</label>
<input asp-for="Suggestion.Title" />
</div>
</td>
</tr>
<div class="up-field">
<label asp-for="Suggestion.Description">توضیحات</label>
<textarea asp-for="Suggestion.Description" class="editor"></textarea>
</div>
<tr>
<td>
تعداد کل:
</td>
<td>
@Model.TotalCount
</td>
</tr>
<div class="up-field">
<label asp-for="Suggestion.PicOrder">ترتیب</label>
<input asp-for="Suggestion.PicOrder" />
</div>
<div class="up-field">
<label asp-for="Suggestion.RejectionCause">علت رد (در صورت رد)</label>
<input asp-for="Suggestion.RejectionCause" />
</div>
</table>
</form>
<div class="up-form-actions">
<button type="submit" name="approve" id="approve" class="up-btn up-btn--success">تأیید</button>
<button type="submit" name="reject" id="reject" class="up-btn up-btn--danger">رد</button>
<button type="submit" name="next" id="next" class="up-btn up-btn--ghost">بعدی</button>
</div>
<p class="up-hint">تعداد کل: @Model.TotalCount</p>
</form>
</div>
}

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.SuggestedPoetSpecLinesModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
@ -6,84 +6,50 @@
ViewData["Title"] = "نکات پیشنهادی برای تصاویر سخنوران";
await GanjooRazor.Utils.GanjoorSessionChecker.ApplyPermissionsToViewData(Request, Response, ViewData);
}
<h1>@ViewData["Title"]</h1>
<div class="up-page-header">
<h1>@ViewData["Title"]</h1>
</div>
@if (Model.LastError != "")
{
<h2>@Model.LastError</h2>
<div class="up-alert up-alert--danger">@Model.LastError</div>
}
else
{
<form method="post">
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">سخنور: </span>
</td>
<td>
<div class="up-card">
<form method="post" class="up-form">
<div class="up-field">
<label>سخنور</label>
<div>
<a href="/photos?p=@Model.Poet.FullUrl.Substring(1)" target="_blank">@Model.Poet.Nickname</a>
<input type="hidden" asp-for="Suggestion.Id" />
<input type="hidden" asp-for="Suggestion.PoetId" />
<input type="hidden" asp-for="Suggestion.LineOrder" />
<input type="hidden" asp-for="Suggestion.SuggestedById" />
</td>
</tr>
<tr>
<td>
<span class="inputlabel">پیشنهاد دهنده: </span>
</td>
<td>
<a href="/hashieha/?userid=@Model.Suggestion.SuggestedById" target="_blank">@Model.Suggestion.SuggestedById</a>
</td>
</tr>
</div>
</div>
<tr>
<td>
<span class="inputlabel">نکته: </span>
</td>
<td>
<textarea asp-for="Suggestion.Contents" class="editor"></textarea>
</td>
</tr>
<tr>
<td>
<button type="submit" name="approve" id="approve" style="width:100%;color:white;background-color:green">تأیید</button>
</td>
<td>
<table style="width:100%" class="noborder">
<tr>
<td>
<span class="inputlabel">علت رد: </span>
<input asp-for="Suggestion.RejectionCause" />
</td>
</tr>
<tr>
<td>
<button type="submit" name="reject" id="reject" style="width:100%;color:white;background-color:darkred">رد</button>
</td>
</tr>
<tr>
<td>
<button type="submit" name="next" id="next" style="width:100%;color:white;background-color:orange">بعدی</button>
</td>
</tr>
</table>
<div class="up-field">
<label>پیشنهاد دهنده</label>
<div><a href="/hashieha/?userid=@Model.Suggestion.SuggestedById" target="_blank">@Model.Suggestion.SuggestedById</a></div>
</div>
</td>
</tr>
<div class="up-field">
<label asp-for="Suggestion.Contents">نکته</label>
<textarea asp-for="Suggestion.Contents" class="editor"></textarea>
</div>
<tr>
<td>
تعداد کل:
</td>
<td>
@Model.TotalCount
</td>
</tr>
<div class="up-field">
<label asp-for="Suggestion.RejectionCause">علت رد (در صورت رد)</label>
<input asp-for="Suggestion.RejectionCause" />
</div>
<div class="up-form-actions">
<button type="submit" name="approve" id="approve" class="up-btn up-btn--success">تأیید</button>
<button type="submit" name="reject" id="reject" class="up-btn up-btn--danger">رد</button>
<button type="submit" name="next" id="next" class="up-btn up-btn--ghost">بعدی</button>
</div>
</table>
</form>
}
<p class="up-hint">تعداد کل: @Model.TotalCount</p>
</form>
</div>
}