improve UI/UX of the User Area

#496
This commit is contained in:
Hamid Reza Mohammadi 2026-08-05 16:00:36 +03:30
parent 2fee534f11
commit f8a26835c0
8 changed files with 176 additions and 602 deletions

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.CatEditsModel
@using RMuseum.Models.Ganjoor
@using RMuseum.Services.Implementation
@ -6,55 +6,33 @@
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
{
if (@Model.CanEdit)
{
<div class="clear-both">
<p>
<a role="button" href="/User/CatEdits?AllUsers=1" class="pagebutton">ویرایش‌های بخش‌های همه</a>
</p>
<div class="up-form-actions">
<a role="button" href="/User/CatEdits?AllUsers=1" class="up-btn up-btn--ghost">ویرایش‌های بخش‌های همه</a>
</div>
}
<partial name="_Pagination" model="Model.PaginationLinks" />
@if (Model.Corrections.Count == 0)
{
<p>
شما هنوز هیچ ویرایشی در بخش‌های انجام نداده‌اید.
</p>
<partial name="_EmptyState" model="@("شما هنوز هیچ ویرایشی در بخش‌های انجام نداده‌اید.")" />
}
<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>
@foreach (var correction in Model.Corrections)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="correction-@correction.Id">
<div class="up-list-item" id="correction-@correction.Id">
<table>
@if (Model.AllUsersEdits)
@ -87,19 +65,7 @@ else
<p style="color:green">@correction.Description</p>
</td>
<td>
@if (correction.Result == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
else
@if (correction.Result == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
<partial name="_ReviewResultBadge" model="correction.Result" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -112,8 +78,6 @@ else
}
}
@if (!string.IsNullOrEmpty(correction.Note))
{
<tr>
@ -134,31 +98,9 @@ else
</tr>
}
</table>
</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

@ -6,12 +6,13 @@
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
{
@ -21,7 +22,7 @@ else
@if (Model.Profile != null)
{
<div id="profile">
<div id="profile" class="up-card">
<p>
<a href="/hashieha?userId=@Model.Profile.Id">@Model.Profile.NickName</a>
@ -38,22 +39,19 @@ else
@Html.Raw(Model.Profile.Bio)
}
</div>
<hr />
}
else
{
<div class="clear-both">
<p>
<a role="button" href="/User/Edits?AllUsers=1" class="pagebutton">ویرایش‌های همه</a>
</p>
<div class="up-form-actions">
<a role="button" href="/User/Edits?AllUsers=1" class="up-btn up-btn--ghost">ویرایش‌های همه</a>
</div>
}
<script>
function rollBackCorrection(correctionId){
if (!confirm('ویرایش معکوس ایجاد شود؟')) {
return;
}
async function rollBackCorrection(correctionId) {
var ok = await upConfirm('ویرایش معکوس ایجاد شود؟');
if (!ok) return;
$.ajax({
type: "POST",
url: '?handler=RollBackCorrection',
@ -61,15 +59,11 @@ else
correctionId: correctionId,
},
success: function () {
alert('انجام شد.');
location.reload(true);
upToast('انجام شد.', 'success');
location.reload(true);
},
error: function (e) {
if (e.responseText == null)
alert(e);
else
alert(e.responseText);
upToast(e.responseText || 'خطایی رخ داد.', 'error');
}
});
@ -78,36 +72,16 @@ else
}
<partial name="_Pagination" model="Model.PaginationLinks" />
@if (Model.Corrections.Count == 0)
{
<p>
شما هنوز هیچ ویرایشی در گنجور انجام نداده‌اید. برای آشنایی با نحوهٔ ویرایش اشعار <a href="https://blog.ganjoor.net/1400/05/23/notes-for-suggesting-corrections/" target="_blank">اینجا</a> را ببینید.
</p>
<partial name="_EmptyState" model="@("شما هنوز هیچ ویرایشی در گنجور انجام نداده‌اید. برای آشنایی با نحوهٔ ویرایش اشعار <a href=\"https://blog.ganjoor.net/1400/05/23/notes-for-suggesting-corrections/\" target=\"_blank\">اینجا</a> را ببینید.")" />
}
<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>
@foreach (var correction in Model.Corrections)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="correction-@correction.Id">
<div class="up-list-item" id="correction-@correction.Id">
<table>
<tr>
<td colspan="3"><a href="/?p=@correction.PoemId" target="_blank">مشاهدهٔ متن شعر یا بخش</a></td>
@ -136,19 +110,7 @@ else
<p style="color:green" id="title-edited-@correction.Id">@correction.Title</p>
</td>
<td>
@if (correction.Result == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
else
@if (correction.Result == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.Result)</p>
}
<partial name="_ReviewResultBadge" model="correction.Result" />
</td>
</tr>
<tr>
@ -181,19 +143,7 @@ else
<p style="color:green">@correction.Rhythm</p>
</td>
<td>
@if (correction.RhythmResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
else
@if (correction.RhythmResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.RhythmResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -217,19 +167,7 @@ else
<p style="color:green" id="summary-edited-@correction.Id">@correction.PoemSummary</p>
</td>
<td>
@if (correction.SummaryReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.SummaryReviewResult)</p>
}
else
@if (correction.SummaryReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green" id="summary-original-@correction.Id">@CorrectionReviewResultConvertor.GetString(correction.SummaryReviewResult)</p>
}
else
{
<p style="color:red" id="summary-edited-@correction.Id">@CorrectionReviewResultConvertor.GetString(correction.SummaryReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.SummaryReviewResult" />
</td>
</tr>
<tr>
@ -263,19 +201,7 @@ else
<p style="color:green">@correction.RhymeLetters</p>
</td>
<td>
@if (correction.RhymeLettersReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
else
@if (correction.RhymeLettersReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.RhymeLettersReviewResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -305,19 +231,7 @@ else
<p style="color:green">@correction.Rhythm2</p>
</td>
<td>
@if (correction.Rhythm2Result == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.Rhythm2Result)</p>
}
else
@if (correction.Rhythm2Result == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.Rhythm2Result)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.Rhythm2Result)</p>
}
<partial name="_ReviewResultBadge" model="correction.Rhythm2Result" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -346,19 +260,7 @@ else
<p style="color:green">@RMuseum.Services.Implementation.GanjoorPoemFormatConvertor.GetString(correction.PoemFormat)</p>
</td>
<td>
@if (correction.PoemFormatReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
else
@if (correction.PoemFormatReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.PoemFormatReviewResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -386,19 +288,7 @@ else
<p>باید حذف شود</p>
</td>
<td>
@if (verse.MarkForDeleteResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.MarkForDeleteResult)</p>
}
else
if (verse.MarkForDeleteResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.MarkForDeleteResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.MarkForDeleteResult)</p>
}
<partial name="_ReviewResultBadge" model="verse.MarkForDeleteResult" />
</td>
</tr>
<tr><td colspan="3" style="background-color:black">&nbsp;</td></tr>
@ -414,19 +304,7 @@ else
<p>@verse.Text</p>
</td>
<td>
@if (verse.NewVerseResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.NewVerseResult)</p>
}
else
if (verse.NewVerseResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.NewVerseResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.NewVerseResult)</p>
}
<partial name="_ReviewResultBadge" model="verse.NewVerseResult" />
</td>
</tr>
<tr><td colspan="3" style="background-color:black">&nbsp;</td></tr>
@ -441,19 +319,7 @@ else
<p style="color:green" id="verse-@verse.Id-edited-@correction.Id">@verse.Text</p>
</td>
<td>
@if (verse.Result == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.Result)</p>
}
else
if (verse.Result == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.Result)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.Result)</p>
}
<partial name="_ReviewResultBadge" model="verse.Result" />
</td>
</tr>
<tr>
@ -483,19 +349,7 @@ else
<p style="color:green" id="verse-summary-@verse.Id-edited-@correction.Id">@verse.CoupletSummary</p>
</td>
<td>
@if (verse.SummaryReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.SummaryReviewResult)</p>
}
else
if (verse.SummaryReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.SummaryReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.SummaryReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="verse.SummaryReviewResult" />
</td>
</tr>
<tr>
@ -528,19 +382,7 @@ else
<p style="color:orange">تبدیل نوع مصرع به @RMuseum.Models.Ganjoor.VersePositionHelper.GetVersePositionString((VersePosition)verse.VersePosition)</p>
</td>
<td>
@if (verse.VersePositionResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.VersePositionResult)</p>
}
else
if (verse.VersePositionResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.VersePositionResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.VersePositionResult)</p>
}
<partial name="_ReviewResultBadge" model="verse.VersePositionResult" />
</td>
</tr>
<tr><td colspan="3" style="background-color:black">&nbsp;</td></tr>
@ -574,19 +416,7 @@ else
}
</td>
<td>
@if (verse.LanguageReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(verse.LanguageReviewResult)</p>
}
else
if (verse.LanguageReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(verse.LanguageReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(verse.LanguageReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="verse.LanguageReviewResult" />
</td>
</tr>
<tr><td colspan="3" style="background-color:black">&nbsp;</td></tr>
@ -616,11 +446,11 @@ else
<td colspan="3">
@if (correction.Reviewed)
{
<a role="button" style="cursor:pointer;width:100%;color:white;background-color:red;display:block" href="/User/Editor?id=@correction.PoemId">ویرایش مجدد</a>
<a role="button" class="up-btn up-btn--danger up-btn--block" href="/User/Editor?id=@correction.PoemId">ویرایش مجدد</a>
}
else
{
<a role="button" style="cursor:pointer;width:100%;color:white;background-color:blue;display:block" href="/User/Editor?id=@correction.PoemId">مشاهده</a>
<a role="button" class="up-btn up-btn--primary up-btn--block" href="/User/Editor?id=@correction.PoemId">مشاهده</a>
}
</td>
</tr>
@ -629,7 +459,7 @@ else
{
<tr>
<td colspan="3">
<a role="button" style="cursor:pointer;width:100%;color:white;background-color:orange;display:block" onclick="rollBackCorrection(@correction.Id)">برگشت به وضعیت قبل از این ویرایش</a>
<a role="button" class="up-btn up-btn--ghost up-btn--block" onclick="rollBackCorrection(@correction.Id)">برگشت به وضعیت قبل از این ویرایش</a>
</td>
</tr>
}
@ -637,27 +467,7 @@ else
</table>
</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,69 +1,42 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.MySuggestedQuotesModel
@{
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>
<partial name="_Pagination" model="Model.PaginationLinks" />
@if (Model.SuggestedQuotes.Count == 0)
{
<p>
شما هنوز هیچ مشق شهری را پیشنهاد نداده‌اید.
</p>
<partial name="_EmptyState" model="@("شما هنوز هیچ مشق شهری را پیشنهاد نداده‌اید.")" />
}
@foreach (var GanjoorQuotedPoem in Model.SuggestedQuotes)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div class="up-list-item" id="bookmark-@GanjoorQuotedPoem.Id">
<div style="background-color:@color" id="bookmark-@GanjoorQuotedPoem.Id">
@if(GanjoorQuotedPoem.Rejected)
@if (GanjoorQuotedPoem.Rejected)
{
<p class="red-color">
رد شده
</p>
<span class="up-badge up-badge--danger">رد شده</span>
}
else
@if (GanjoorQuotedPoem.Published)
else if (GanjoorQuotedPoem.Published)
{
<p class="green-color">
تأیید شده
</p>
<span class="up-badge up-badge--success">تأیید شده</span>
}
else
{
<p>
بررسی نشده
</p>
<span class="up-badge up-badge--primary">بررسی نشده</span>
}
@if (GanjoorQuotedPoem.Rejected)
{
@ -72,7 +45,6 @@ else
</p>
}
<table>
<tr>
@ -80,7 +52,7 @@ else
<a href="/?p=@GanjoorQuotedPoem.PoemId">شعر مرجع</a>:
</td>
</tr>
<tr>
<td>
شاعر مرجع:
@ -118,7 +90,7 @@ else
</tr>
<tr>
<td>
<input type="checkbox" @(GanjoorQuotedPoem.RelatedCoupletVerse1ShouldBeEmphasized ? "checked=\"checked\"" : "") />
<input type="checkbox" disabled @(GanjoorQuotedPoem.RelatedCoupletVerse1ShouldBeEmphasized ? "checked=\"checked\"" : "") />
</td>
</tr>
<tr>
@ -139,7 +111,7 @@ else
</tr>
<tr>
<td>
<input type="checkbox" @(GanjoorQuotedPoem.RelatedCoupletVerse2ShouldBeEmphasized ? "checked=\"checked\"" : "") />
<input type="checkbox" disabled @(GanjoorQuotedPoem.RelatedCoupletVerse2ShouldBeEmphasized ? "checked=\"checked\"" : "") />
</td>
</tr>
@ -150,7 +122,7 @@ else
</tr>
<tr>
<td>
<input type="checkbox" @(GanjoorQuotedPoem.ClaimedByBothPoets ? "checked=\"checked\"" : "") />
<input type="checkbox" disabled @(GanjoorQuotedPoem.ClaimedByBothPoets ? "checked=\"checked\"" : "") />
</td>
</tr>
<tr>
@ -226,25 +198,8 @@ else
</tr>
</table>
</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,116 +1,87 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.MySuggestedSongsModel
@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>
<partial name="_Pagination" model="Model.PaginationLinks" />
@if (Model.SuggestedSongs.Count == 0)
{
<p>
شما هنوز هیچ آهنگ مرتبطی را پیشنهاد نداده‌اید. برای آشنایی با نحوهٔ پیشنهاد آهنگ‌های مرتبط <a href="https://blog.ganjoor.net/1395/06/28/bptags/" target="_blank">اینجا</a> را ببینید.
</p>
<partial name="_EmptyState" model="@("شما هنوز هیچ آهنگ مرتبطی را پیشنهاد نداده‌اید. برای آشنایی با نحوهٔ پیشنهاد آهنگ‌های مرتبط <a href=\"https://blog.ganjoor.net/1395/06/28/bptags/\" target=\"_blank\">اینجا</a> را ببینید.")" />
}
@foreach (var suggestedSong in Model.SuggestedSongs)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="bookmark-@suggestedSong.Id">
<p>
وضعیت: @(suggestedSong.Rejected ? "رد شده" : suggestedSong.Approved ? "تأیید شده" : "بررسی نشده" )
</p>
@if (suggestedSong.Rejected)
{
<p>
دلیل رد: @suggestedSong.RejectionCause
</p>
}
@if (suggestedSong.BrokenLink)
{
<p>لینک آهنگ کار نمی‌کند.</p>
}
<p>
<a href="@($"/?p={suggestedSong.PoemId}")" target="_blank">مشاهدهٔ شعر مرتبط</a>
</p>
@if (!string.IsNullOrEmpty(suggestedSong.ArtistName))
{
<p>
خواننده: <a href="@Html.Raw(suggestedSong.ArtistUrl)" target="_blank">@suggestedSong.ArtistName</a>
</p>
}
@if (!string.IsNullOrEmpty(suggestedSong.AlbumName))
{
<p>
آلبوم: <a href="@Html.Raw(suggestedSong.AlbumUrl)" target="_blank">@suggestedSong.AlbumName</a>
</p>
}
<p>
آهنگ: <a href="@Html.Raw(suggestedSong.TrackUrl)" target="_blank">@suggestedSong.TrackName</a>
</p>
@if (!string.IsNullOrEmpty(suggestedSong.Description))
{
<p>توضیح: @suggestedSong.Description</p>
}
</div>
<hr />
}
<p style="text-align:center">
@foreach (var paginationLink in Model.PaginationLinks)
<div class="up-list">
@foreach (var suggestedSong in Model.SuggestedSongs)
{
if (!string.IsNullOrEmpty(paginationLink.Url))
{
<a href="@paginationLink.Url">@paginationLink.Name</a>
}
else
{
@paginationLink.Name
}
<div class="up-list-item" id="bookmark-@suggestedSong.Id">
@if (suggestedSong.Rejected)
{
<span class="up-badge up-badge--danger">رد شده</span>
}
else if (suggestedSong.Approved)
{
<span class="up-badge up-badge--success">تأیید شده</span>
}
else
{
<span class="up-badge up-badge--primary">بررسی نشده</span>
}
@if (suggestedSong.Rejected)
{
<p>
دلیل رد: @suggestedSong.RejectionCause
</p>
}
@if (suggestedSong.BrokenLink)
{
<div class="up-alert up-alert--warning">لینک آهنگ کار نمی‌کند.</div>
}
<p>
<a href="@($"/?p={suggestedSong.PoemId}")" target="_blank">مشاهدهٔ شعر مرتبط</a>
</p>
@if (!string.IsNullOrEmpty(suggestedSong.ArtistName))
{
<p>
خواننده: <a href="@Html.Raw(suggestedSong.ArtistUrl)" target="_blank">@suggestedSong.ArtistName</a>
</p>
}
@if (!string.IsNullOrEmpty(suggestedSong.AlbumName))
{
<p>
آلبوم: <a href="@Html.Raw(suggestedSong.AlbumUrl)" target="_blank">@suggestedSong.AlbumName</a>
</p>
}
<p>
آهنگ: <a href="@Html.Raw(suggestedSong.TrackUrl)" target="_blank">@suggestedSong.TrackName</a>
</p>
@if (!string.IsNullOrEmpty(suggestedSong.Description))
{
<p>توضیح: @suggestedSong.Description</p>
}
</div>
}
</p>
</div>
<partial name="_Pagination" model="Model.PaginationLinks" />
}

View File

@ -1,4 +1,4 @@
@page
@page
@model GanjooRazor.Areas.User.Pages.SectionEditsModel
@using RMuseum.Models.Ganjoor
@using RMuseum.Services.Implementation
@ -6,55 +6,33 @@
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
{
if (@Model.CanEdit)
{
<div class="clear-both">
<p>
<a role="button" href="/User/SectionEdits?AllUsers=1" class="pagebutton">ویرایش‌های قطعات همه</a>
</p>
<div class="up-form-actions">
<a role="button" href="/User/SectionEdits?AllUsers=1" class="up-btn up-btn--ghost">ویرایش‌های قطعات همه</a>
</div>
}
<partial name="_Pagination" model="Model.PaginationLinks" />
@if (Model.Corrections.Count == 0)
{
<p>
شما هنوز هیچ ویرایشی در گنجور انجام نداده‌اید. برای آشنایی با نحوهٔ ویرایش اشعار <a href="https://blog.ganjoor.net/1400/05/23/notes-for-suggesting-corrections/" target="_blank">اینجا</a> را ببینید.
</p>
<partial name="_EmptyState" model="@("شما هنوز هیچ ویرایشی در گنجور انجام نداده‌اید. برای آشنایی با نحوهٔ ویرایش اشعار <a href=\"https://blog.ganjoor.net/1400/05/23/notes-for-suggesting-corrections/\" target=\"_blank\">اینجا</a> را ببینید.")" />
}
<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>
@foreach (var correction in Model.Corrections)
{
if (color == "gray")
color = "lightsteelblue";
else
color = "gray";
<div style="background-color:@color" id="correction-@correction.Id">
<div class="up-list-item" id="correction-@correction.Id">
<table>
<tr>
<td colspan="3"><a href="/User/Section?poemId=@correction.PoemId&index=@correction.SectionIndex" target="_blank">مشاهدهٔ متن شعر یا بخش</a></td>
@ -83,19 +61,7 @@ else
<p style="color:green">@correction.Rhythm</p>
</td>
<td>
@if (correction.RhythmResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
else
@if (correction.RhythmResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.RhythmResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.RhythmResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -118,19 +84,7 @@ else
<p style="color:green">@correction.RhymeLetters</p>
</td>
<td>
@if (correction.RhymeLettersReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
else
@if (correction.RhymeLettersReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.RhymeLettersReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.RhymeLettersReviewResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -153,19 +107,7 @@ else
<p style="color:green">@correction.Language</p>
</td>
<td>
@if (correction.LanguageReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.LanguageReviewResult)</p>
}
else
@if (correction.LanguageReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.LanguageReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.LanguageReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.LanguageReviewResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -188,19 +130,7 @@ else
<p style="color:green">@RMuseum.Services.Implementation.GanjoorPoemFormatConvertor.GetString(correction.PoemFormat)</p>
</td>
<td>
@if (correction.PoemFormatReviewResult == CorrectionReviewResult.NotReviewed)
{
<p style="color:blue">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
else
@if (correction.PoemFormatReviewResult == CorrectionReviewResult.Approved)
{
<p style="color:green">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
else
{
<p style="color:red">@CorrectionReviewResultConvertor.GetString(correction.PoemFormatReviewResult)</p>
}
<partial name="_ReviewResultBadge" model="correction.PoemFormatReviewResult" />
</td>
</tr>
@if (!string.IsNullOrEmpty(correction.ReviewNote))
@ -266,39 +196,18 @@ else
<td colspan="3">
@if (correction.Reviewed)
{
<a role="button" style="cursor:pointer;width:100%;color:white;background-color:red;display:block" href="/User/Section?poemId=@correction.PoemId&index=@correction.SectionIndex">ویرایش مجدد</a>
<a role="button" class="up-btn up-btn--danger up-btn--block" href="/User/Section?poemId=@correction.PoemId&index=@correction.SectionIndex">ویرایش مجدد</a>
}
else
{
<a role="button" style="cursor:pointer;width:100%;color:white;background-color:blue;display:block" href="/User/Section?poemId=@correction.PoemId&index=@correction.SectionIndex">مشاهده</a>
<a role="button" class="up-btn up-btn--primary up-btn--block" href="/User/Section?poemId=@correction.PoemId&index=@correction.SectionIndex">مشاهده</a>
}
</td>
</tr>
</table>
</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

@ -0,0 +1,17 @@
@*
Renders a correction review result (NotReviewed/Approved/Rejected...)
as a colored badge instead of an ad hoc <p style="color:...">.
Used on Edits.cshtml / CatEdits.cshtml / SectionEdits.cshtml.
<partial name="_ReviewResultBadge" model="correction.Result" />
*@
@model RMuseum.Models.Ganjoor.CorrectionReviewResult
@{
var cssClass = Model switch
{
RMuseum.Models.Ganjoor.CorrectionReviewResult.NotReviewed => "up-badge--primary",
RMuseum.Models.Ganjoor.CorrectionReviewResult.Approved => "up-badge--success",
_ => "up-badge--danger",
};
}
<span class="up-badge @cssClass">@RMuseum.Services.Implementation.CorrectionReviewResultConvertor.GetString(Model)</span>

View File

@ -0,0 +1 @@
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

View File

@ -1,40 +1,9 @@
# User panel Phase 0 + Phase 1 — file package
# GanjoorService
Ganjoor museum and ganjoor.net own backend (ASP.NET Core Web API) and frontend (Razor Pages) code
This contains the FULL, current content of every file touched by Phase 0
(shared components/foundations) and Phase 1 (nav grouping + dashboard)
combined. Since you already have Phase 0 applied, copying these over is
a no-op for the Phase-0-only files and just adds the Phase 1 changes.
این کد وب سرویس [گنجینهٔ گنجور](https://museum.ganjoor.net) و [گنجور](https://ganjoor.net) و همچنین کد سایت گنجور است.
Copy each file below into the same relative path under your
`GanjoorService/GanjooRazor/` folder, overwriting what's there.
[فهرست توابع در دسترس](https://api.ganjoor.net)
## New files (Phase 0)
- wwwroot/css/user-panel.css
- wwwroot/js/user-panel.js
- Areas/User/Pages/Shared/_Pagination.cshtml
- Areas/User/Pages/Shared/_EmptyState.cshtml
- Areas/User/Pages/Shared/_Toasts.cshtml
- Areas/User/Pages/Shared/_ConfirmModal.cshtml
![https://api.ganjoor.net](https://user-images.githubusercontent.com/582212/91652208-14a63c00-eaaa-11ea-89c2-5acabdfda7de.png)
## Modified files (Phase 0 + Phase 1, combined into their final state)
- Pages/Shared/_UserPanelLayout.cshtml
(Phase 0: loads user-panel.css/js, includes toast/modal hosts.
Phase 1: navbar regrouped into dropdowns.)
- Areas/User/Pages/Notifications.cshtml
(Phase 0 demo: uses the new pagination/empty-state partials,
upConfirm/upToast instead of confirm()/alert().)
- Areas/User/Pages/Index.cshtml
(Phase 1: dashboard greeting, quick-links grid, forms wrapped in cards.)
## After copying
1. Diff against what you have now (or just eyeball it — none of these
files are huge) to make sure nothing local got clobbered.
2. Build.
3. Load `/User/Index` and `/User/Notifications` and click around:
nav dropdowns, the confirm-modal on delete, toasts on notification
actions, the quick-links grid.
4. Commit and push however you normally would.
No backend/API/.csproj changes in either phase — these are all under
`wwwroot/` or `Areas/User/Pages/` (Razor views + one stylesheet + one
script).