SimpleLMS
|
|
@ -0,0 +1,34 @@
|
|||
@model CourseModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
@{
|
||||
//page title
|
||||
ViewBag.PageTitle = T("SimpleLMS.Add").Text + " " + T("SimpleLMS.Course");
|
||||
//active menu item (system name)
|
||||
NopHtml.SetActiveMenuItemSystemName("SimpleLMS.Courses");
|
||||
}
|
||||
|
||||
|
||||
<form asp-controller="Course" asp-action="Create" method="post" id="product-form">
|
||||
<div class="content-header clearfix">
|
||||
<h1 class="float-left">
|
||||
@T("SimpleLMS.Add") @T("SimpleLMS.Course")
|
||||
<small>
|
||||
<i class="fas fa-arrow-circle-left"></i>
|
||||
<a asp-action="List">@T("SimpleLMS.BackToList")</a>
|
||||
</small>
|
||||
</h1>
|
||||
<div class="float-right">
|
||||
<button type="submit" name="save" class="btn btn-primary">
|
||||
<i class="far fa-save"></i>
|
||||
@T("Admin.Common.Save")
|
||||
</button>
|
||||
<button type="submit" name="save-continue" class="btn btn-primary">
|
||||
<i class="far fa-save"></i>
|
||||
@T("Admin.Common.SaveContinue")
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@await Html.PartialAsync("_CreateOrUpdate.cshtml", Model)
|
||||
</form>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
@model CourseModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
@{
|
||||
//page title
|
||||
ViewBag.PageTitle = T("SimpleLMS.Edit").Text + " " + T("SimpleLMS.Course");
|
||||
//active menu item (system name)
|
||||
NopHtml.SetActiveMenuItemSystemName("SimpleLMS.Courses");
|
||||
}
|
||||
|
||||
@*<link href="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/css/jquery-ui-1.10.4.custom.min.css")" rel="stylesheet" type="text/css" />*@
|
||||
<link href="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/css/simplelms.css")" type="text/css" rel="stylesheet" />
|
||||
@*<script type="text/javascript" src="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/js/jquery-ui-1.10.4.custom.min.js")"></script>*@
|
||||
|
||||
|
||||
|
||||
<form asp-controller="Course" asp-action="Edit" method="post" id="product-form">
|
||||
<input type="hidden" id="Id" name="Id" value="@Model.Id" />
|
||||
<div class="content-header clearfix">
|
||||
<h1 class="float-left">
|
||||
@T("SimpleLMS.Edit") @T("SimpleLMS.Course") - @Model.Name
|
||||
<small>
|
||||
<i class="fas fa-arrow-circle-left"></i>
|
||||
<a asp-action="List">@T("SimpleLMS.BackToList")</a>
|
||||
</small>
|
||||
</h1>
|
||||
<div class="float-right">
|
||||
|
||||
<button type="submit" name="save" class="btn btn-primary">
|
||||
<i class="far fa-save"></i>
|
||||
@T("Admin.Common.Save")
|
||||
</button>
|
||||
<button type="submit" name="save-continue" class="btn btn-primary">
|
||||
<i class="far fa-save"></i>
|
||||
@T("Admin.Common.SaveContinue")
|
||||
</button>
|
||||
|
||||
<span id="course-delete" class="btn btn-danger">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
@T("Admin.Common.Delete")
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@await Html.PartialAsync("_CreateOrUpdate.cshtml", Model)
|
||||
</form>
|
||||
<nop-delete-confirmation asp-model-id="@Model.Id" asp-button-id="course-delete" />
|
||||
<script src="@Url.Content("~/js/public.common.js")"></script>
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
@model CourseSearchModel
|
||||
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
@{
|
||||
//page title
|
||||
ViewBag.PageTitle = T("SimpleLMS.CourseList").Text;
|
||||
//active menu item (system name)
|
||||
NopHtml.SetActiveMenuItemSystemName("SimpleLMS.Courses");
|
||||
}
|
||||
|
||||
@{
|
||||
const string hideSearchBlockAttributeName = "CourseListPage.HideSearchBlock";
|
||||
var hideSearchBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName);
|
||||
}
|
||||
|
||||
|
||||
<form asp-controller="Course" asp-action="List" method="post">
|
||||
<div class="content-header clearfix">
|
||||
<h1 class="float-left">
|
||||
@T("SimpleLMS.CourseList")
|
||||
</h1>
|
||||
<div class="float-right">
|
||||
<a asp-action="Create" class="btn btn-primary">
|
||||
<i class="fas fa-plus-square"></i>
|
||||
@T("Admin.Common.AddNew")
|
||||
</a>
|
||||
@*<button type="button" id="delete-selected" class="btn btn-danger">
|
||||
<i class="far fa-trash-alt"></i>
|
||||
@T("Admin.Common.Delete.Selected")
|
||||
</button>*@
|
||||
@*<nop-action-confirmation asp-button-id="delete-selected" />*@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="form-horizontal">
|
||||
<div class="cards-group">
|
||||
<div class="card card-default card-search">
|
||||
<div class="card-body">
|
||||
<div class="row search-row @(!hideSearchBlock ? "opened" : "")" data-hideAttribute="@hideSearchBlockAttributeName">
|
||||
<div class="search-text">@T("Admin.Common.Search")</div>
|
||||
<div class="icon-search"><i class="fas fa-search" aria-hidden="true"></i></div>
|
||||
<div class="icon-collapse"><i class="far fa-angle-@(!hideSearchBlock ? "up" : "down")" aria-hidden="true"></i></div>
|
||||
</div>
|
||||
|
||||
<div class="search-body @(hideSearchBlock ? "closed" : "")">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="form-group row">
|
||||
<div class="col-md-4">
|
||||
<nop-label asp-for="SearchCourseName" />
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<nop-editor asp-for="SearchCourseName" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="text-center col-12">
|
||||
<button type="button" id="search-courses" class="btn btn-primary btn-search">
|
||||
<i class="fas fa-search"></i>
|
||||
@T("Admin.Common.Search")
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-default">
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
@await Html.PartialAsync("Table", new DataTablesModel
|
||||
{
|
||||
Name = "courses-grid",
|
||||
UrlRead = new DataUrl("CourseList", "Course", null),
|
||||
SearchButtonId = "search-courses",
|
||||
Length = Model.PageSize,
|
||||
LengthMenu = Model.AvailablePageSizes,
|
||||
Filters = new List<FilterParameter>
|
||||
{
|
||||
new FilterParameter(nameof(Model.SearchCourseName))
|
||||
},
|
||||
ColumnCollection = new List<ColumnProperty>
|
||||
{
|
||||
new ColumnProperty(nameof(CourseModel.Id))
|
||||
{
|
||||
IsMasterCheckBox = true,
|
||||
Render = new RenderCheckBox("checkbox_courses"),
|
||||
ClassName = NopColumnClassDefaults.CenterAll,
|
||||
Width = "50"
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Name))
|
||||
{
|
||||
Title = T("SimpleLMS.Name").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Instructor))
|
||||
{
|
||||
Title = T("SimpleLMS.Instructor").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Category))
|
||||
{
|
||||
Title = T("SimpleLMS.Category").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.SectionsTotal))
|
||||
{
|
||||
Title = T("SimpleLMS.Sections").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.EnrolledStudents))
|
||||
{
|
||||
Title = T("SimpleLMS.EnrolledStudents").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Status))
|
||||
{
|
||||
Title = T("SimpleLMS.Status").Text
|
||||
},
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Price))
|
||||
{
|
||||
Title = T("SimpleLMS.Price").Text
|
||||
},
|
||||
|
||||
|
||||
new ColumnProperty(nameof(CourseModel.Id))
|
||||
{
|
||||
Title = T("Admin.Common.Edit").Text,
|
||||
Width = "80",
|
||||
ClassName = NopColumnClassDefaults.Button,
|
||||
Render = new RenderButtonEdit(new DataUrl("Edit"))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
$(document).ready(function () {
|
||||
$('#delete-selected-action-confirmation-submit-button').bind('click', function () {
|
||||
var postData = {
|
||||
selectedIds: selectedIds
|
||||
};
|
||||
addAntiForgeryToken(postData);
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: "POST",
|
||||
url: "@(Url.Action("DeleteSelected", "Course"))",
|
||||
data: postData,
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
$('#deleteSelectedFailed-info').text(errorThrown);
|
||||
$('#deleteSelectedFailed').click();
|
||||
},
|
||||
complete: function (jqXHR, textStatus) {
|
||||
updateTable('#courses-grid');
|
||||
}
|
||||
});
|
||||
$('#delete-selected-action-confirmation').modal('toggle');
|
||||
return false;
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<nop-alert asp-alert-id="deleteSelectedFailed" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</form>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
@model AttachmentModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header"> @Html.DisplayText(Model.Name)</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
</h5>
|
||||
<p class="card-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
@model CourseModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
@if (Model.Id > 0)
|
||||
{
|
||||
<div class="text-center">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="add-section">@T("SimpleLMS.Add") @T("SimpleLMS.Section")</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" id="sort-sections" onclick="sortSections(@Model.Id)">@T("SimpleLMS.Sort") @T("SimpleLMS.Sections")</button>
|
||||
</div>
|
||||
<div class="card-body" id="sections">
|
||||
@* @await Html.PartialAsync("_CreateOrUpdate.Sections.cshtml", Model.Sections);*@
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
refreshSections();
|
||||
$('#add-section').on('click',
|
||||
function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
@*displayPopupContentFromUrl('@Url.Action("CreateSection", "Course")?courseId=@Model.Id',
|
||||
'@T("SimpleLMS.CreateNewSection")');*@
|
||||
|
||||
$('<div id="create-or-edit-section-modal" class="form-horizontal"></div>').load('@Url.Action("CreateSection", "Course")?courseId=@Model.Id')
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Create") @T("SimpleLMS.Section")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#delete-anything-close-dialog').click(function () {
|
||||
closeConfirmDialog();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function closeConfirmDialog() {
|
||||
$('#delete-anything').dialog("close");
|
||||
}
|
||||
|
||||
function editSection(sectionId)
|
||||
{
|
||||
|
||||
$('<div id="create-or-edit-section-modal" class="form-horizontal"></div>').load('@Url.Action("EditSection", "Course")?sectionId=' + sectionId)
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Edit") @T("SimpleLMS.Section")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function refreshSections() {
|
||||
$("#sections").load('@Url.Action("Sections", "Course")' + '?courseId=@Model.Id');
|
||||
}
|
||||
|
||||
function addLesson(sectionId,courseId)
|
||||
{
|
||||
$('<div id="create-or-edit-lesson-modal" class="form-horizontal"></div>').load('@Url.Action("CreateLesson", "Course")?sectionId=' + sectionId + '&courseId=' + courseId)
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Create") @T("SimpleLMS.Lesson")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
removeTinymce();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function editLesson(lessonId,sectionId,courseId)
|
||||
{
|
||||
$('<div id="create-or-edit-lesson-modal" class="form-horizontal"></div>').load('@Url.Action("EditLesson", "Course")?lessonId=' + lessonId + '§ionId=' + sectionId + '&courseId=' + courseId)
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Edit") @T("SimpleLMS.Lesson")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
removeTinymce();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sortLessons(sectionId, courseId)
|
||||
{
|
||||
$('<div id="sort-modal" class="form-horizontal"></div>').load('@Url.Action("SortLessons", "Course")?sectionId=' + sectionId)
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Sort") @T("SimpleLMS.Lessons")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
removeTinymce();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function sortSections(courseId)
|
||||
{
|
||||
$('<div id="sort-modal" class="form-horizontal"></div>').load('@Url.Action("SortSections", "Course")?courseId=' + courseId)
|
||||
.dialog({
|
||||
modal: true,
|
||||
width: 800,
|
||||
position: {
|
||||
of: window, my: "top+100", at: "top"
|
||||
},
|
||||
maxHeight: $(window).height() - 20,
|
||||
title: '@T("SimpleLMS.Sort") @T("SimpleLMS.Sections")',
|
||||
close: function (event, ui) {
|
||||
$(this).dialog('destroy').remove();
|
||||
removeTinymce();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function deleteLesson(lessonId,sectionId,courseId)
|
||||
{
|
||||
|
||||
openDialog();
|
||||
|
||||
$('#delete-anything-submit-button').off();
|
||||
|
||||
$('#delete-anything-submit-button').on('click',
|
||||
function (e) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action("DeleteLesson", "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
lessonId: lessonId,
|
||||
sectionId: sectionId,
|
||||
courseId: courseId
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
closeConfirmDialog();
|
||||
$('#deleteSelectedFailed-info').text(jqXHR.responseText + ' ' + errorThrown);
|
||||
$('#deleteSelectedFailed').click();
|
||||
},
|
||||
complete: function (jqXHR, textStatus) {
|
||||
closeConfirmDialog();
|
||||
refreshSections();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function deleteSection(sectionId)
|
||||
{
|
||||
|
||||
openDialog();
|
||||
|
||||
$('#delete-anything-submit-button').off();
|
||||
$('#delete-anything-submit-button').on('click',
|
||||
function(e) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action("DeleteSection", "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
sectionId: sectionId
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
closeConfirmDialog();
|
||||
$('#deleteSelectedFailed-info').text(jqXHR.responseText + ' ' + errorThrown);
|
||||
$('#deleteSelectedFailed').click();
|
||||
},
|
||||
complete: function (jqXHR, textStatus) {
|
||||
closeConfirmDialog();
|
||||
refreshSections();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function deleteCourse(courseId)
|
||||
{
|
||||
|
||||
openDialog();
|
||||
|
||||
$('#delete-anything-submit-button').off();
|
||||
$('#delete-anything-submit-button').on('click',
|
||||
function(e) {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action("Delete", "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
courseId: courseId
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
closeConfirmDialog();
|
||||
$('#deleteSelectedFailed-info').text(jqXHR.responseText + ' ' + errorThrown);
|
||||
$('#deleteSelectedFailed').click();
|
||||
},
|
||||
complete: function (jqXHR, textStatus) {
|
||||
closeConfirmDialog();
|
||||
refreshSections();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function openDialog() {
|
||||
$('#delete-anything').dialog({
|
||||
resizable: false,
|
||||
height: "auto",
|
||||
width: 400,
|
||||
modal: true,
|
||||
title: '@T("Admin.Common.AreYouSure")'
|
||||
});
|
||||
}
|
||||
|
||||
function removeTinymce() {
|
||||
while (tinymce.editors.length > 0) {
|
||||
tinymce.remove(tinymce.editors[0]);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<nop-alert asp-alert-id="deleteSelectedFailed" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="alert alert-warning alert-dismissible fade show" role="alert">
|
||||
@T("SimpleLMS.SaveCourseToAddContentMessage")
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
<div id="delete-anything" style="display: none;">
|
||||
<div class="modal-body">
|
||||
@T("Admin.Common.DeleteConfirmation")
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" id="delete-anything-submit-button" class="btn btn-primary float-right">
|
||||
@T("Admin.Common.Yes")
|
||||
</button> <span class="btn btn-default float-right margin-r-5" data-dismiss="modal" id="delete-anything-close-dialog">
|
||||
@T("Admin.Common.NoCancel")
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
@model CourseModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="ProductId" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-select asp-for="ProductId" asp-items="Model.AvailableProducts" asp-required="true" />
|
||||
<span asp-validation-for="ProductId"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="Name"/>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="Name" asp-required="true" />
|
||||
<span asp-validation-for="Name"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
@model LessonModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
<div class="card bg-white ml-3" >
|
||||
<div class="card-header border-info">
|
||||
|
||||
@if (Model.LessonType == Nop.Plugin.Misc.SimpleLMS.Domains.LessonType.Video)
|
||||
{
|
||||
<img src='@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/images/video-player.png")' height="16" class="mr-3" />
|
||||
}
|
||||
else if (Model.LessonType == Nop.Plugin.Misc.SimpleLMS.Domains.LessonType.Text)
|
||||
{
|
||||
<img src='@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/images/text.png")' height="16" class="mr-3" />
|
||||
}
|
||||
|
||||
|
||||
@Model.DisplayOrder. Lesson: <strong>@Model.Name</strong>
|
||||
|
||||
|
||||
|
||||
@if (Model.IsFreeLesson)
|
||||
{
|
||||
<span class='badge badge-success ml-2'>Free</span>
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div class="float-right">
|
||||
<button type="button" class="btn btn-primary btn-sm" onclick="editLesson(@Model.Id,@Model.SectionId,@Model.CourseId)" id="edit-lesson-@Model.Id">@T("SimpleLMS.Edit") @T("SimpleLMS.Lesson")</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="delete-lesson-@Model.Id" onclick="deleteLesson(@Model.Id,@Model.SectionId,@Model.CourseId)">@T("SimpleLMS.Delete") @T("SimpleLMS.Lesson")</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
@model LessonModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
<form asp-controller="Course" asp-action="CreateLesson" method="post" id="lesson-form">
|
||||
|
||||
<div class="card-body" id="create-or-edit-lesson">
|
||||
|
||||
<input type="hidden" id="Id" name="Id" value="@Model.Id" />
|
||||
<input type="hidden" id="CourseId" name="CourseId" value="@Model.CourseId" />
|
||||
<input type="hidden" id="SectionId" name="SectionId" value="@Model.SectionId" />
|
||||
<input type="hidden" id="DisplayOrder" name="DisplayOrder" value="@Model.DisplayOrder" />
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="Name" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="Name" asp-required="true" />
|
||||
<span asp-validation-for="Name"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="IsFreeLesson" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="IsFreeLesson" asp-required="false" />
|
||||
<span asp-validation-for="IsFreeLesson"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="LessonType" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-select asp-for="LessonType" asp-items="Model.AvailableLessonTypes" asp-required="true" />
|
||||
<span asp-validation-for="LessonType"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="lesson-contents">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="LessonContents" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="LessonContents" asp-template="RichEditor" />
|
||||
<span asp-validation-for="LessonContents"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="video-type">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VideoType" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-select asp-for="VideoType" asp-items="Model.AvailableVideoTypes" asp-required="true" />
|
||||
<span asp-validation-for="VideoType"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="video-id-from-provider">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VideoIdFromProvider" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VideoIdFromProvider" asp-required="true" />
|
||||
<span asp-validation-for="VideoIdFromProvider"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="video-embed-code">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VideoEmbedCode" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VideoEmbedCode" asp-required="true" />
|
||||
<span asp-validation-for="VideoEmbedCode"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="video-url">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VideoUrl" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VideoUrl" asp-required="true" />
|
||||
<span asp-validation-for="VideoUrl"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="video-duration">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="Duration" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="Duration" asp-required="true" />
|
||||
<span asp-validation-for="Duration"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row" id="attachment-type">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="AttachmentType" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-select asp-for="AttachmentType" asp-items="Model.AvailableAttachmentTypes" asp-required="true" />
|
||||
<span asp-validation-for="AttachmentType"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group row" id="submit-button">
|
||||
<div class="col-md-3">
|
||||
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="add-lesson-submit">
|
||||
@(Model.Id>0 ? T("SimpleLMS.Update") + " " + @T("SimpleLMS.Lesson") : T("SimpleLMS.Add") + " " + @T("SimpleLMS.Lesson"))
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
$('#add-lesson-submit').off();
|
||||
|
||||
$('#add-lesson-submit').on('click',
|
||||
function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var _form = $(this).closest("form");
|
||||
_form.removeData('validator');
|
||||
_form.removeData('unobtrusiveValidation');
|
||||
$.validator.unobtrusive.parse(_form);
|
||||
|
||||
var isValid = $(_form).validate().form();
|
||||
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//alert();
|
||||
|
||||
|
||||
//alert($('#create-or-edit-section').serialize());
|
||||
$(this).prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action((Model.Id>0? "EditLesson": "CreateLesson"), "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
id: $("#create-or-edit-lesson").find("#Id").val(),
|
||||
courseId: $("#create-or-edit-lesson").find("#CourseId").val(),
|
||||
sectionId: $("#create-or-edit-lesson").find("#SectionId").val(),
|
||||
displayOrder: $("#create-or-edit-lesson").find("#DisplayOrder").val(),
|
||||
name: $("#create-or-edit-lesson").find("#Name").val(),
|
||||
isFreeLesson: $("#create-or-edit-lesson").find("#IsFreeLesson").is(":checked"),
|
||||
lessonType: $("#create-or-edit-lesson").find("#LessonType").val(),
|
||||
videoType: $("#create-or-edit-lesson").find("#VideoType").val(),
|
||||
videoIdFromProvider: $("#create-or-edit-lesson").find("#VideoIdFromProvider").val(),
|
||||
duration: $("#create-or-edit-lesson").find("#Duration").val(),
|
||||
lessonContents: tinymce.get("LessonContents").getContent({ format: "html" })
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken":
|
||||
$('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
$("form").removeData("unobtrusiveValidation");
|
||||
$.validator.unobtrusive.parse("form");
|
||||
$('#create-or-edit-lesson-modal').dialog('destroy').remove();
|
||||
removeTinymce();
|
||||
refreshSections();
|
||||
},
|
||||
failure: function (response) {
|
||||
$('#add-lesson-submit').prop('disabled', false);
|
||||
alert(JSON.stringify(response));
|
||||
},
|
||||
error: function (response) {
|
||||
|
||||
let obj = JSON.parse(response.responseText);
|
||||
var errorArray = {};
|
||||
|
||||
$.each(obj, function (key, value) {
|
||||
errorArray[key] = value;
|
||||
});
|
||||
|
||||
|
||||
|
||||
try {
|
||||
$('#lesson-form').data('validator').showErrors(errorArray);
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
}
|
||||
|
||||
$('#add-lesson-submit').prop('disabled', false);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$("#LessonType").change(function () {
|
||||
lessonTypeChange();
|
||||
});
|
||||
|
||||
hidelAll();
|
||||
lessonTypeChange();
|
||||
|
||||
});
|
||||
|
||||
|
||||
function lessonTypeChange() {
|
||||
|
||||
hidelAll();
|
||||
|
||||
var lessonTypeText = $('#LessonType').find(":selected").text();
|
||||
|
||||
if (lessonTypeText == "Video") {
|
||||
$("#video-type").show();
|
||||
$("#video-id-from-provider").show();
|
||||
$("#video-duration").show();
|
||||
$("#lesson-contents").show();
|
||||
}
|
||||
else if (lessonTypeText == "Text") {
|
||||
$("#lesson-contents").show();
|
||||
}
|
||||
else if (lessonTypeText == "Document") {
|
||||
$("#attachment-type").show();
|
||||
}
|
||||
$("#submit-button").show();
|
||||
}
|
||||
|
||||
function hidelAll() {
|
||||
$("#lesson-contents").hide();
|
||||
$("#video-type").hide();
|
||||
$("#video-id-from-provider").hide();
|
||||
$("#video-embed-code").hide();
|
||||
$("#video-url").hide();
|
||||
$("#video-duration").hide();
|
||||
$("#attachment-type").hide();
|
||||
$("#submit-button").hide();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</form>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@model IList<LessonModel>
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@foreach (var lesson in Model)
|
||||
{
|
||||
@await Html.PartialAsync("_CreateOrUpdate.Lesson.cshtml", lesson)
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
@model SectionModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header">
|
||||
|
||||
@Model.DisplayOrder. @T("SimpleLMS.Section"): <strong>@Model.Title</strong>
|
||||
@if (Model.IsFree)
|
||||
{
|
||||
<span class='badge badge-success ml-2'>Free</span>
|
||||
}
|
||||
<div class="float-right">
|
||||
<button type="button" class="btn btn-primary btn-sm" onclick="editSection(@Model.Id)" id="edit-section-@Model.Id">@T("SimpleLMS.Edit") @T("SimpleLMS.Section")</button>
|
||||
<button type="button" class="btn btn-primary btn-sm" onclick="addLesson(@Model.Id,@Model.CourseId)" id="add-lesson-@Model.Id">@T("SimpleLMS.Add") @T("SimpleLMS.Lesson")</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" id="sort-lessons-@Model.Id" onclick="sortLessons(@Model.Id,@Model.CourseId)">@T("SimpleLMS.Sort") @T("SimpleLMS.Lessons")</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" id="delete-section-@Model.Id" onclick="deleteSection(@Model.Id)">@T("SimpleLMS.Delete") @T("SimpleLMS.Section")</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (Model.Lessons != null && Model.Lessons.Count > 0)
|
||||
{
|
||||
|
||||
@await Html.PartialAsync("_CreateOrUpdate.Lessons.cshtml", Model.Lessons)
|
||||
}
|
||||
else
|
||||
{
|
||||
<h5 class="card-title">
|
||||
<strong> @T("SimpleLMS.NoLessonsAvailable")</strong>
|
||||
</h5>
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
@model SectionModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
<form asp-controller="Course" asp-action="CreateSection" method="post" id="section-form">
|
||||
<div class="card-body" id="create-or-edit-section">
|
||||
|
||||
<input type="hidden" id="Id" name="Id" value="@Model.Id" />
|
||||
<input type="hidden" id="CourseId" name="CourseId" value="@Model.CourseId" />
|
||||
<input type="hidden" id="DisplayOrder" name="DisplayOrder" value="@Model.DisplayOrder" />
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="Title" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="Title" asp-required="true" />
|
||||
<span asp-validation-for="Title"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="IsFree" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="IsFree" asp-required="false" />
|
||||
<span asp-validation-for="IsFree"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<button type="button" class="btn btn-primary btn-sm" id="add-section-submit">
|
||||
@(Model.Id>0 ? T("SimpleLMS.Update") + " " + @T("SimpleLMS.Section") : T("SimpleLMS.Add") + " " + @T("SimpleLMS.Section"))
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
$('#add-lesson-submit').off();
|
||||
|
||||
$('#add-section-submit').on('click',
|
||||
function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var _form = $(this).closest("form");
|
||||
_form.removeData('validator');
|
||||
_form.removeData('unobtrusiveValidation');
|
||||
$.validator.unobtrusive.parse(_form);
|
||||
|
||||
var isValid = $(_form).validate().form();
|
||||
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//alert($('#create-or-edit-section').serialize());
|
||||
$(this).prop('disabled', true);
|
||||
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action((Model.Id > 0 ? "EditSection" : "CreateSection"), "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
id: $("#create-or-edit-section").find("#Id").val(),
|
||||
courseId: $("#create-or-edit-section").find("#CourseId").val(),
|
||||
displayOrder: $("#create-or-edit-section").find("#DisplayOrder").val(),
|
||||
title: $("#create-or-edit-section").find("#Title").val(),
|
||||
isFree: $("#create-or-edit-section").find("#IsFree").is(":checked")
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken":
|
||||
$('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
success: function (response) {
|
||||
$('#create-or-edit-section-modal').dialog('destroy').remove();
|
||||
refreshSections();
|
||||
},
|
||||
failure: function (response) {
|
||||
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop('enabled', false);
|
||||
|
||||
},
|
||||
error: function (response) {
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop('enabled', false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</form>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
@model IList<SectionModel>
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
@foreach (var section in Model)
|
||||
{
|
||||
@await Html.PartialAsync("_CreateOrUpdate.Section.cshtml", section)
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
@model SortableEntity
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Domains;
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
<form method="post" id="sort-form">
|
||||
|
||||
<div class="card-body" id="sort">
|
||||
|
||||
<input type="hidden" id="ParentId" name="ParentId" value="@Model.ParentId" />
|
||||
<input type="hidden" id="SortRecordType" name="SortRecordType" value="@Model.SortRecordType" />
|
||||
|
||||
<ul id="sort-records" class="list-group bg-white">
|
||||
@if (Model.SortRecords != null && Model.SortRecords.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < Model.SortRecords.Count; i++)
|
||||
{
|
||||
<li class="ui-state-default list-group-item mb-1 all-scroll border-0" id="@Model.SortRecords[i].Id">
|
||||
<span class="border-1 border-info">
|
||||
<strong> @Model.SortRecords[i].DisplayText</strong>
|
||||
</span>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="form-group row mt-3" id="submit-button">
|
||||
|
||||
<div class="col-md-12">
|
||||
@if (Model.SortRecords != null && Model.SortRecords.Count > 0)
|
||||
{
|
||||
<button type="button" class="btn btn-primary btn-sm float-right" id="sort-submit">
|
||||
@T("SimpleLMS.Update")
|
||||
</button>
|
||||
}
|
||||
else if (@Model.SortRecordType == SortRecordType.Section)
|
||||
{
|
||||
<span>
|
||||
@T("SimpleLMS.NoSectionsAvailable")
|
||||
</span>
|
||||
}
|
||||
else if (@Model.SortRecordType == SortRecordType.Lesson)
|
||||
{
|
||||
<span>
|
||||
@T("SimpleLMS.NoLessonsAvailable")
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
$("#sort-records").sortable();
|
||||
|
||||
|
||||
$("#sort-records").disableSelection();
|
||||
|
||||
$('#sort-submit').off();
|
||||
|
||||
$('#sort-submit').on('click',
|
||||
function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
var idsInOrder = $("#sort-records").sortable("toArray");
|
||||
|
||||
|
||||
var _form = $(this).closest("form");
|
||||
_form.removeData('validator');
|
||||
_form.removeData('unobtrusiveValidation');
|
||||
$.validator.unobtrusive.parse(_form);
|
||||
|
||||
var isValid = $(_form).validate().form();
|
||||
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(this).prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '@Url.Action((Model.SortRecordType == SortRecordType.Lesson ? "SortLessons" : "SortSections"), "Course")',
|
||||
//data: $('#create-or-edit-section').serialize(),
|
||||
data: {
|
||||
parentId: $("#sort").find("#ParentId").val(),
|
||||
sortRecordType: $("#sort").find("#SortRecordType").val(),
|
||||
newSortOrderValues: JSON.stringify(idsInOrder),
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken":
|
||||
$('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
$("form").removeData("unobtrusiveValidation");
|
||||
$.validator.unobtrusive.parse("form");
|
||||
$('#sort-modal').dialog('destroy').remove();
|
||||
|
||||
refreshSections();
|
||||
},
|
||||
failure: function (response) {
|
||||
$('#sort-submit').prop('disabled', false);
|
||||
alert(JSON.stringify(response));
|
||||
},
|
||||
error: function (response) {
|
||||
try {
|
||||
|
||||
let obj = JSON.parse(response.responseText);
|
||||
var errorArray = {};
|
||||
|
||||
$.each(obj, function (key, value) {
|
||||
errorArray[key] = value;
|
||||
});
|
||||
|
||||
$('#sort-form').data('validator').showErrors(errorArray);
|
||||
}
|
||||
catch (e) {
|
||||
alert(response.responseText);
|
||||
}
|
||||
|
||||
$('#sort-submit').prop('disabled', false);
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style type="text/css">
|
||||
.all-scroll {
|
||||
cursor: all-scroll;
|
||||
}
|
||||
</style>
|
||||
|
||||
</form>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
@model VideoModel
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="card bg-light mb-3">
|
||||
<div class="card-header"> @Model.Duration</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
</h5>
|
||||
<p class="card-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
</script>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
@model CourseModel
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
|
||||
@{
|
||||
|
||||
const string hideInfoBlockAttributeName = "CoursePage.HideInfoBlock";
|
||||
|
||||
var hideInfoBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideInfoBlockAttributeName);
|
||||
|
||||
const string hideCourseContentBlockAttributeName = "CoursePage.HideCourseContentBlock";
|
||||
|
||||
var hideCourseContentBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideCourseContentBlockAttributeName);
|
||||
|
||||
NopHtml.AddScriptParts(ResourceLocation.Footer, "~/lib_npm/tinymce/tinymce.min.js", excludeFromBundle: true);
|
||||
|
||||
}
|
||||
<div asp-validation-summary="All"></div>
|
||||
<input asp-for="Id" type="hidden" />
|
||||
|
||||
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="form-horizontal">
|
||||
|
||||
|
||||
|
||||
<nop-cards id="course-cards">
|
||||
<nop-card asp-name="course-info" asp-icon="fas fa-info" asp-title="@T("SimpleLMS.Course") @T("SimpleLMS.Info")"
|
||||
asp-hide-block-attribute-name="@hideInfoBlockAttributeName" asp-hide="@hideInfoBlock" asp-advanced="false">
|
||||
@await Html.PartialAsync("_CreateOrUpdate.Info.cshtml", Model)
|
||||
</nop-card>
|
||||
|
||||
<nop-card asp-name="course-content" asp-icon="fas fa-info" asp-title="@T("SimpleLMS.CourseContent")"
|
||||
asp-hide-block-attribute-name="@hideCourseContentBlockAttributeName" asp-hide="@hideCourseContentBlock" asp-advanced="false">
|
||||
@await Html.PartialAsync("_CreateOrUpdate.CourseContent.cshtml", Model)
|
||||
</nop-card>
|
||||
</nop-cards>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
@model ConfigurationModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
@{
|
||||
const string hideYouTubeBlockAttributeName = "Configuration.HideYouTubeBlock";
|
||||
|
||||
var hideYouTubeBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideYouTubeBlockAttributeName);
|
||||
|
||||
const string hideVimeoBlockAttributeName = "Configuration.HideVimeoBlock";
|
||||
|
||||
var hideVimeoBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideVimeoBlockAttributeName);
|
||||
|
||||
const string hideVdoCipherBlockAttributeName = "Configuration.HideVdoCipherBlock";
|
||||
|
||||
var hideVdoCipherBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideVdoCipherBlockAttributeName);
|
||||
|
||||
|
||||
//active menu item (system name)
|
||||
NopHtml.SetActiveMenuItemSystemName("SimpleLMS.configuration");
|
||||
}
|
||||
|
||||
@*<link href="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/css/jquery-ui-1.10.4.custom.min.css")" rel="stylesheet" type="text/css" />*@
|
||||
@*<link href="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/css/simplelms.css")" type="text/css" rel="stylesheet" />*@
|
||||
@*<script type="text/javascript" src="@Url.Content("~/Plugins/Misc.SimpleLMS/Content/Admin/js/jquery-ui-1.10.4.custom.min.js")"></script>*@
|
||||
|
||||
<form asp-controller="Settings" asp-action="Configure" method="post">
|
||||
<section class="content">
|
||||
<div class="container-fluid">
|
||||
<div class="cards-group">
|
||||
<div class="card card-default">
|
||||
<div class="card-header">
|
||||
@T("Plugins.SimpleLMS.Configuration.PageTitle")
|
||||
</div>
|
||||
<div class="card-body form-horizontal">
|
||||
<nop-cards id="course-cards">
|
||||
@*<nop-card asp-name="YouTube" asp-icon="fas fa-info" asp-title="@T("SimpleLMS.Configuration.Youtube")" asp-hide-block-attribute-name="@hideYouTubeBlockAttributeName" asp-hide="@hideYouTubeBlock" asp-advanced="false">@await Html.PartialAsync("_CreateOrUpdate.Youtube.cshtml", Model)</nop-card>*@
|
||||
|
||||
<nop-card asp-name="Vimeo" asp-icon="fas fa-info" asp-title="@T("SimpleLMS.Configuration.Vimeo")" asp-hide-block-attribute-name="@hideVimeoBlockAttributeName" asp-hide="@hideVimeoBlock" asp-advanced="false">@await Html.PartialAsync("_CreateOrUpdate.Vimeo.cshtml", Model)</nop-card>
|
||||
@*<nop-card asp-name="VdoCipher" asp-icon="fas fa-info" asp-title="@T("SimpleLMS.Configuration.VdoCipher")" asp-hide-block-attribute-name="@hideVdoCipherBlockAttributeName" asp-hide="@hideVdoCipherBlock" asp-advanced="false">@await Html.PartialAsync("_CreateOrUpdate.VdoCipher.cshtml", Model)</nop-card>*@
|
||||
|
||||
</nop-cards>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card card-default">
|
||||
<div class="card-body">
|
||||
<div class="form-group row">
|
||||
<div class="col-md-9 offset-md-3">
|
||||
<button type="submit" name="save" class="btn btn-primary">@T("Admin.Common.Save")</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
@model ConfigurationModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VdoCipherKey" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VdoCipherKey" asp-required="true" />
|
||||
<span asp-validation-for="VdoCipherKey"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
@model ConfigurationModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VimeoClient" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VimeoClient" asp-required="true" />
|
||||
<span asp-validation-for="VimeoClient"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VimeoSecret" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VimeoSecret" asp-required="true" />
|
||||
<span asp-validation-for="VimeoSecret"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="VimeoAccess" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="VimeoAccess" asp-required="true" />
|
||||
<span asp-validation-for="VimeoAccess"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
@model ConfigurationModel
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Areas.Admin.Models
|
||||
@using Nop.Core.Domain.Catalog;
|
||||
@using Nop.Services
|
||||
@using Nop.Services.Stores
|
||||
|
||||
|
||||
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
<div class="card-body">
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-md-3">
|
||||
<nop-label asp-for="YouTubeApiKey" />
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<nop-editor asp-for="YouTubeApiKey" asp-required="true" />
|
||||
<span asp-validation-for="YouTubeApiKey"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
@inherits Nop.Web.Framework.Mvc.Razor.NopRazorPage<TModel>
|
||||
|
||||
@inject IGenericAttributeService genericAttributeService
|
||||
@inject IWorkContext workContext
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Nop.Web.Framework
|
||||
|
||||
@using System.Text.Encodings.Web
|
||||
@using Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||
@using Microsoft.AspNetCore.Routing
|
||||
@using Microsoft.Extensions.Primitives
|
||||
@using Nop.Core
|
||||
@using Nop.Core.Domain.Common
|
||||
@using Nop.Core.Events
|
||||
@using Nop.Core.Infrastructure
|
||||
@using Nop.Services.Common
|
||||
@using static Nop.Services.Common.NopLinksDefaults
|
||||
@using Nop.Web.Areas.Admin.Models.Affiliates
|
||||
@using Nop.Web.Areas.Admin.Models.Blogs
|
||||
@using Nop.Web.Areas.Admin.Models.Catalog
|
||||
@using Nop.Web.Areas.Admin.Models.Cms
|
||||
@using Nop.Web.Areas.Admin.Models.Common
|
||||
@using Nop.Web.Areas.Admin.Models.Customers
|
||||
@using Nop.Web.Areas.Admin.Models.Directory
|
||||
@using Nop.Web.Areas.Admin.Models.Discounts
|
||||
@using Nop.Web.Areas.Admin.Models.ExternalAuthentication
|
||||
@using Nop.Web.Areas.Admin.Models.Forums
|
||||
@using Nop.Web.Areas.Admin.Models.Home
|
||||
@using Nop.Web.Areas.Admin.Models.Localization
|
||||
@using Nop.Web.Areas.Admin.Models.Logging
|
||||
@using Nop.Web.Areas.Admin.Models.Messages
|
||||
@using Nop.Web.Areas.Admin.Models.MultiFactorAuthentication
|
||||
@using Nop.Web.Areas.Admin.Models.News
|
||||
@using Nop.Web.Areas.Admin.Models.Orders
|
||||
@using Nop.Web.Areas.Admin.Models.Payments
|
||||
@using Nop.Web.Areas.Admin.Models.Plugins
|
||||
@using Nop.Web.Areas.Admin.Models.Plugins.Marketplace
|
||||
@using Nop.Web.Areas.Admin.Models.Polls
|
||||
@using Nop.Web.Areas.Admin.Models.Reports
|
||||
@using Nop.Web.Areas.Admin.Models.Security
|
||||
@using Nop.Web.Areas.Admin.Models.Settings
|
||||
@using Nop.Web.Areas.Admin.Models.Shipping
|
||||
@using Nop.Web.Areas.Admin.Models.ShoppingCart
|
||||
@using Nop.Web.Areas.Admin.Models.Stores
|
||||
@using Nop.Web.Areas.Admin.Models.Tasks
|
||||
@using Nop.Web.Areas.Admin.Models.Tax
|
||||
@using Nop.Web.Areas.Admin.Models.Templates
|
||||
@using Nop.Web.Areas.Admin.Models.Topics
|
||||
@using Nop.Web.Areas.Admin.Models.Vendors
|
||||
@using Nop.Web.Extensions
|
||||
@using Nop.Web.Framework
|
||||
@using Nop.Web.Framework.Menu
|
||||
@using Nop.Web.Framework.Models
|
||||
@using Nop.Web.Framework.Events
|
||||
@using Nop.Web.Framework.Extensions
|
||||
@using Nop.Web.Framework.Infrastructure
|
||||
@using Nop.Web.Framework.Models.DataTables
|
||||
@using Nop.Web.Framework.Security.Captcha
|
||||
@using Nop.Web.Framework.Security.Honeypot
|
||||
@using Nop.Web.Framework.Themes
|
||||
@using Nop.Web.Framework.UI
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
.ajax-loading-block-window {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 999;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: -16px 0 0 -16px;
|
||||
background: url('../images/loading.gif') center no-repeat;
|
||||
}
|
||||
|
||||
.please-wait {
|
||||
background: url('../images/ajax-loader-small.gif') no-repeat;
|
||||
padding-left: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ui-dialog {
|
||||
max-width: 90%;
|
||||
border: 1px solid #ddd;
|
||||
box-shadow: 0 0 2px rgba(0,0,0,0.15);
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
/*override jQuery UI styles, do not delete doubled properties*/
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
font: normal 14px Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
.ui-dialog:before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar {
|
||||
border-bottom: 1px solid #ddd;
|
||||
overflow: hidden;
|
||||
background-color: #eee;
|
||||
padding: 10px 15px;
|
||||
/*override jQuery UI styles, do not delete doubled properties*/
|
||||
border-width: 0 0 1px;
|
||||
border-radius: 0;
|
||||
background-image: none;
|
||||
padding: 10px 15px !important;
|
||||
font-weight: normal;
|
||||
cursor: auto !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar > span {
|
||||
float: left;
|
||||
font-size: 18px;
|
||||
color: #444;
|
||||
/*override jQuery UI styles, do not delete doubled properties*/
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
background: url('../images/close.png') center no-repeat;
|
||||
font-size: 0;
|
||||
/*override jQuery UI styles, do not delete doubled properties*/
|
||||
top: 0 !important;
|
||||
right: 0 !important;
|
||||
width: 42px !important;
|
||||
height: 42px !important;
|
||||
margin: 0 !important;
|
||||
border: none !important;
|
||||
border-radius: 0;
|
||||
background: url('../images/close.png') center no-repeat !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.ui-dialog-titlebar button span {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ui-dialog-content {
|
||||
padding: 15px;
|
||||
line-height: 20px;
|
||||
/*override jQuery UI styles, do not delete doubled properties*/
|
||||
background-color: #fff !important;
|
||||
padding: 15px 15px 20px 15px !important;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.ui-dialog-content .page {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.ui-dialog-content .page-title {
|
||||
min-height: 0;
|
||||
margin: 0 0 15px;
|
||||
padding: 0px 10px 10px 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ui-dialog-content .page-title h1 {
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ui-dialog-content .back-in-stock-subscription-page {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ui-dialog-content .back-in-stock-subscription-page .tooltip {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.ui-dialog-content .back-in-stock-subscription-page .button-1 {
|
||||
border: none;
|
||||
background-color: #4ab2f1;
|
||||
padding: 10px 15px;
|
||||
font-size: 15px;
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.ui-dialog-content .back-in-stock-subscription-page .button-1:hover,
|
||||
.ui-dialog-content .back-in-stock-subscription-page .button-1:focus {
|
||||
background-color: #248ece;
|
||||
}
|
||||
|
After Width: | Height: | Size: 673 B |
|
After Width: | Height: | Size: 989 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -0,0 +1,208 @@
|
|||
.hide-overflow-x {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.cstm-nav .nav-link {
|
||||
padding-right: 1rem !important;
|
||||
padding-left: 1rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.course-page .about-course h5 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.course-page .list-group.side-menu {
|
||||
font-size: 0.85rem;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.course-page .side-menu .list-group-item {
|
||||
padding: 0;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.course-page .duration {
|
||||
line-height: 1.4;
|
||||
font-size: 12px;
|
||||
color: #6c757d
|
||||
}
|
||||
|
||||
.side-menu a, .dropdown-btn {
|
||||
text-decoration: none;
|
||||
color: #222;
|
||||
display: block;
|
||||
border: none;
|
||||
background: none;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
padding: 8px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.side-menu a, .dropdown-btn:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.side-menu .list-group-item.side-menu-title {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.side-menu a:hover, .dropdown-btn:hover {
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
.dropdown-container {
|
||||
display: none;
|
||||
padding: 8px 0;
|
||||
transition: 0.3s ease-out;
|
||||
}
|
||||
|
||||
.dropdown-container a:hover, .dropdown-container a:hover.active {
|
||||
background-color: #D1D7DC;
|
||||
}
|
||||
|
||||
.fa-caret-down {
|
||||
float: right;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
[data-toggle="collapse"] .fa:before {
|
||||
content: "\f0d7";
|
||||
}
|
||||
|
||||
[data-toggle="collapse"].collapsed .fa:before {
|
||||
content: "\f0da";
|
||||
}
|
||||
|
||||
.vertical-align {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
.course-lesson {
|
||||
}
|
||||
|
||||
.course-lesson:hover {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.course-lesson-active {
|
||||
background: #d1d7dc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes growProgressBar {
|
||||
0%, 33% {
|
||||
--pgPercentage: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
--pgPercentage: var(--value);
|
||||
}
|
||||
}
|
||||
|
||||
@property --pgPercentage {
|
||||
syntax: '<number>';
|
||||
inherits: false;
|
||||
initial-value: 0;
|
||||
}
|
||||
|
||||
div[role="progressbar"] {
|
||||
--size: 3.5rem;
|
||||
--fg: #369;
|
||||
--bg: #def;
|
||||
--pgPercentage: var(--value);
|
||||
animation: growProgressBar 3s 1 forwards;
|
||||
width: var(--size);
|
||||
height: var(--size);
|
||||
border-radius: 50%;
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
background: radial-gradient(closest-side, white 80%, transparent 0 99.9%, white 0), conic-gradient(var(--fg) calc(var(--pgPercentage) * 1%), var(--bg) 0);
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: calc(var(--size) / 5);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
div[role="progressbar"]::before {
|
||||
counter-reset: percentage var(--value);
|
||||
content: counter(percentage) '%';
|
||||
}
|
||||
|
||||
#loader {
|
||||
position: fixed;
|
||||
width: 200px;
|
||||
padding: 10px;
|
||||
left: 45%;
|
||||
top: 0;
|
||||
display: none;
|
||||
background-color: #fff;
|
||||
z-index: 99999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.video-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.video-container {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.video-container::after {
|
||||
padding-top: 56.25%;
|
||||
display: block;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.video-container iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#loaddiv {
|
||||
height: 60vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 648px) {
|
||||
#loaddiv {
|
||||
height: 50vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
#loaddiv {
|
||||
height: 40vh;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Nop.Plugin.Misc.SimpleLMS.Infrastructure
|
||||
{
|
||||
public class ViewLocationExpander : IViewLocationExpander
|
||||
{
|
||||
public void PopulateValues(ViewLocationExpanderContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
|
||||
{
|
||||
if (context.AreaName == "Admin")
|
||||
{
|
||||
viewLocations = new[] { $"/Plugins/Misc.SimpleLMS/Areas/Admin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
|
||||
}
|
||||
//else if (context.AreaName == null && context.ViewName == "Components/CustomerNavigation/Default")
|
||||
//{
|
||||
// viewLocations = new[] { $"/Plugins/Misc.SimpleLMS/Views/Shared/Components/CustomCustomerNavigation/Default.cshtml" }.Concat(viewLocations);
|
||||
//}
|
||||
else
|
||||
{
|
||||
viewLocations = new[] { $"/Plugins/Misc.SimpleLMS/Views/{context.ControllerName}/{context.ViewName}.cshtml"
|
||||
}.Concat(viewLocations);
|
||||
}
|
||||
|
||||
return viewLocations;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
@model CourseDetail
|
||||
@using Nop.Core
|
||||
@using Nop.Core.Domain.Catalog
|
||||
@inject CatalogSettings catalogSettings
|
||||
@inject IWorkContext workContext
|
||||
@{
|
||||
|
||||
}
|
||||
@{
|
||||
var sectionCount = 1;
|
||||
var lessonCount = 1;
|
||||
Layout = "_CourseDetailRoot";
|
||||
|
||||
NopHtml.AddTitleParts(Model.Name);
|
||||
|
||||
NopHtml.AddCssFileParts("~/lib_npm/bootstrap/css/bootstrap.min.css");
|
||||
NopHtml.AddCssFileParts("~/lib_npm/@fortawesome/fontawesome-free/css/all.min.css");
|
||||
NopHtml.AddCssFileParts("~/Plugins/Misc.SimpleLMS/Content/Public/Productstyle.css");
|
||||
//<link rel="stylesheet" href="~/Plugins/Misc.SimpleLMS/Content/Public/Productstyle.css" />
|
||||
|
||||
NopHtml.AddScriptParts(ResourceLocation.Footer, "~/lib_npm/bootstrap/js/bootstrap.min.js");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-dark cstm-nav bg-dark">
|
||||
|
||||
|
||||
@await Component.InvokeAsync("Logo")
|
||||
|
||||
@*<a class="navbar-brand" href="@Url.Action("mycourses","customer")">@T("SimpleLMS.MyCourses")</a>*@
|
||||
<span class="course-title text-light pl-2"> @Model.Name</span>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link">
|
||||
<div role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="--value:@(Model.Progress);height:30px;width:30px;"></div>
|
||||
@Model.CompletedLessons @T("SimpleLMS.Of") @Model.TotalLessons @T("SimpleLMS.Completed")
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="page-wrapper">
|
||||
<section class="course-page">
|
||||
<div class="hide-overflow-x">
|
||||
<div class="row">
|
||||
<div class="col-md-9 pr-0">
|
||||
@if (Model.Sections.Count == 0)
|
||||
{
|
||||
<div class="m-3 p-3">
|
||||
<p class="text-danger"> @T("SimpleLMS.NoLessonsAvailable")</p>
|
||||
</div>
|
||||
}
|
||||
<div id="loaddiv">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 pl-md-0">
|
||||
<div class="accordion vh-100 overflow-auto" id="accordion@(Model.Id)">
|
||||
@foreach (var section in Model.Sections)
|
||||
{
|
||||
<div class="card">
|
||||
<div class="card-header p-0" id="heading@(section.Id)">
|
||||
<h2 class="p-2 m-0">
|
||||
<button class="btn btn-link btn-block text-left text-decoration-none text-dark" type="button" data-toggle="collapse" data-target="#collapse@(section.Id)" aria-expanded="true"
|
||||
aria-controls="collapse@(section.Id)">
|
||||
<strong> @T("SimpleLMS.Section") @(sectionCount++): @(section.Title)</strong>
|
||||
<i class="fa fa-caret-down"></i>
|
||||
|
||||
|
||||
<div class="duration">
|
||||
@(section.CompletedLessons) / @(section.TotalLessons)
|
||||
@(section.Duration>0? "| " + section.Duration + " " +T("SimpleLMS.Minutes"):"")
|
||||
</div>
|
||||
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
<div id="collapse@(section.Id)" class="collapse show" aria-labelledby="heading@(section.Id)">
|
||||
<div class="card-body p-0">
|
||||
|
||||
@foreach (var lesson in section.Lessons)
|
||||
{<div class="course-lesson p-2 pl-3" id="lesson_@lesson.Id">
|
||||
<div class="form-check">
|
||||
|
||||
<label class="vertical-align">
|
||||
<input type="checkbox" data-course="@(Model.Id)" data-section="@(section.Id)" @(lesson.IsCompleted ? "checked" : "")
|
||||
data-lesson="@(lesson.Id)" class="form-check-input is-complete" data-iscompleted="@lesson.IsCompleted" />
|
||||
</label>
|
||||
|
||||
<span>
|
||||
<a class="showCource text-secondary text-decoration-none p-1" style="max-width:100%;" href="javascript:void(0)" data-lesson="@lesson.Id" data-course="@lesson.CourseId">
|
||||
@(lessonCount++). @lesson.Name
|
||||
</a>
|
||||
</span>
|
||||
<div class="duration ml-2">
|
||||
<small class="text-muted">
|
||||
@if (lesson.LessonType == Nop.Plugin.Misc.SimpleLMS.Domains.LessonType.Video)
|
||||
{
|
||||
<i class="fa fa-play-circle pr-1" aria-hidden="true"></i>
|
||||
}
|
||||
@if (lesson.LessonType == Nop.Plugin.Misc.SimpleLMS.Domains.LessonType.Text)
|
||||
{
|
||||
<i class="fa fa-sticky-note"></i>
|
||||
}
|
||||
|
||||
@(lesson.Duration>0? lesson.Duration+ " " + @T("SimpleLMS.Minutes"):"")
|
||||
|
||||
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
|
||||
$(function () {
|
||||
$(document).ajaxStart(function () {
|
||||
$("#loader").show();
|
||||
});
|
||||
|
||||
$(document).ajaxStop(function () {
|
||||
$("#loader").hide();
|
||||
});
|
||||
|
||||
$(document).ajaxError(function () {
|
||||
$("#loader").hide();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$(".showCource").on("click", function () {
|
||||
let lessonId = $(this).data("lesson");
|
||||
let courseId = $(this).data("course");
|
||||
loadLesson(lessonId, courseId);
|
||||
});
|
||||
|
||||
$(".is-complete").change(function () {
|
||||
|
||||
let isChecked = $(this).is(":checked");
|
||||
|
||||
let lessonId = $(this).data("lesson");
|
||||
let courseId = $(this).data("course");
|
||||
let sectionId = $(this).data("section");
|
||||
|
||||
console.log($(this).data("lesson"));
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/customer/updatelessonstatus',
|
||||
data: {
|
||||
courseId: courseId,
|
||||
sectionId: sectionId,
|
||||
lessonId: lessonId,
|
||||
isCompleted: isChecked
|
||||
},
|
||||
headers: {
|
||||
"RequestVerificationToken":
|
||||
$('input:hidden[name="__RequestVerificationToken"]').val()
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
},
|
||||
failure: function (response) {
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop("checked", !isChecked);
|
||||
|
||||
},
|
||||
error: function (response) {
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop("checked", !isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('.collapse').collapse({
|
||||
toggle: false
|
||||
});
|
||||
|
||||
loadLesson('@Model.CurrentLesson','@Model.Id');
|
||||
|
||||
|
||||
|
||||
});
|
||||
function loadLesson(lessonId, courseId) {
|
||||
$.get('/Customer/LessonContent?lessonId=' + lessonId + '&courseId=' + courseId, function (data) {
|
||||
$("#loaddiv").html("");
|
||||
$("#loaddiv").html(data);
|
||||
});
|
||||
|
||||
$('.course-lesson').removeClass("course-lesson-active");
|
||||
$('#lesson_' + lessonId).addClass("course-lesson-active");
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
<script src="https://player.vimeo.com/api/player.js"></script>
|
||||
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
@model CourseSearchModel
|
||||
|
||||
|
||||
|
||||
@{
|
||||
Layout = "_ColumnsTwo";
|
||||
NopHtml.AddTitleParts(T("SimpleLMS.MyCourses").Text);
|
||||
|
||||
}
|
||||
|
||||
@section left
|
||||
{
|
||||
@await Component.InvokeAsync("CustomerNavigation", new { selectedTabId = SimpleLMSDefaults.CustomerMyCoursesMenuTab })
|
||||
}
|
||||
|
||||
|
||||
|
||||
<div class="page account-page customer-info-page">
|
||||
<div class="page-title course-title-box flex-container">
|
||||
<h1 class="d-inline">@T("SimpleLMS.MyCourses")</h1>
|
||||
<div class="search-box store-search-box course-search-box push" id="course-search-div">
|
||||
<form id="search-courses-form">
|
||||
<input type="text" class="search-box-text" id="search-course-name" autocomplete="off" name="SearchCourseName" placeholder="@T("SimpleLMS.SearchCourses")"
|
||||
aria-label="@T("Search.SearchBox.Text.Label")" />
|
||||
|
||||
<button type="submit" id="course-search" class="button-1 search-box-button">@T("Search.Button")</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-body">
|
||||
|
||||
<!--Search-->
|
||||
<div class="products-container">
|
||||
<div class="ajax-products-busy"></div>
|
||||
<div class="products-wrapper" id="course-list-parent">
|
||||
@*@await Html.PartialAsync("_MyCourseList", Model.CourseOverviewList)*@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style type="text/css">
|
||||
|
||||
.course-title-box {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.course-title-box .push {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.course-search-box input.search-box-text {
|
||||
width: 150px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script asp-location="Footer">$(document).ready(function () {
|
||||
|
||||
$('#search-courses-form').submit(
|
||||
function (e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var _form = $(this).closest("form");
|
||||
_form.removeData('validator');
|
||||
_form.removeData('unobtrusiveValidation');
|
||||
$.validator.unobtrusive.parse(_form);
|
||||
|
||||
var isValid = $(_form).validate().form();
|
||||
|
||||
if (!isValid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$(this).prop('disabled', true);
|
||||
|
||||
var searchTerm = $("#course-search-div").find("#search-course-name").val();
|
||||
var pageNumber = 1;
|
||||
|
||||
setQueryString('keyword', searchTerm);
|
||||
setQueryString('page', pageNumber);
|
||||
|
||||
getCourseData(pageNumber, searchTerm);
|
||||
|
||||
});
|
||||
|
||||
loadCourses();
|
||||
|
||||
|
||||
});
|
||||
|
||||
function getCourseData(pageNo, searchTerm) {
|
||||
|
||||
var data = {
|
||||
searchCourseName: searchTerm,
|
||||
pageNumber: pageNo
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/customer/searchmycourses',
|
||||
data: JSON.stringify(data),
|
||||
headers: {
|
||||
"RequestVerificationToken":
|
||||
$('input:hidden[name="__RequestVerificationToken"]').val(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
success: function (response) {
|
||||
$('#course-list-parent').html(response);
|
||||
$(this).prop('enabled', false);
|
||||
},
|
||||
failure: function (response) {
|
||||
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop('enabled', false);
|
||||
|
||||
},
|
||||
error: function (response) {
|
||||
alert(JSON.stringify(response));
|
||||
$(this).prop('enabled', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function addPagerHandlers() {
|
||||
|
||||
|
||||
$('.pager [data-page]').each(function () {
|
||||
var hrefl = $(this).attr('href');
|
||||
var url = new URL(hrefl);
|
||||
|
||||
var seachText = getQueryString('keyword');
|
||||
|
||||
if (!seachText)
|
||||
seachText = '';
|
||||
|
||||
url.searchParams.set("keyword", seachText);
|
||||
var newUrl = url.href;
|
||||
$(this).attr("href", newUrl);
|
||||
|
||||
});
|
||||
|
||||
|
||||
$('.pager [data-page]').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var seachText = getQueryString('keyword');
|
||||
|
||||
if (!seachText)
|
||||
seachText = '';
|
||||
|
||||
setQueryString("page", $(this).data('page'));
|
||||
|
||||
getCourseData($(this).data('page'), seachText);
|
||||
|
||||
return false;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function loadCourses() {
|
||||
|
||||
var keyword = getQueryString('keyword');
|
||||
|
||||
if (!keyword)
|
||||
keyword = '';
|
||||
|
||||
var page = getQueryString('page');
|
||||
|
||||
if (!page || isNaN(page))
|
||||
page = '1';
|
||||
|
||||
$("#course-search-div").find("#search-course-name").val(keyword);
|
||||
|
||||
getCourseData(page, keyword);
|
||||
}
|
||||
|
||||
function getQueryString(key) {
|
||||
const url = new URL(window.location.href);
|
||||
return url.searchParams.get(key);
|
||||
}
|
||||
|
||||
function setQueryString(key, value) {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set(key, value);
|
||||
window.history.replaceState(null, null, url);
|
||||
}</script>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
@{
|
||||
Layout = "_Root.Head";
|
||||
}
|
||||
@await Component.InvokeAsync("Widget", new { widgetZone = PublicWidgetZones.BodyStartHtmlTagAfter })
|
||||
@{ await Html.RenderPartialAsync("_Notifications"); }
|
||||
@{ await Html.RenderPartialAsync("_JavaScriptDisabledWarning"); }
|
||||
@{ await Html.RenderPartialAsync("_OldInternetExplorerWarning"); }
|
||||
|
||||
<div class=" loader-overlay" id="loader">
|
||||
<div class="spinner-border text-primary" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@RenderBody()
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
@model Nop.Plugin.Misc.SimpleLMS.Models.LessonDetail
|
||||
@using Nop.Core
|
||||
@using Nop.Core.Domain.Catalog
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Domains
|
||||
@inject CatalogSettings catalogSettings
|
||||
@inject IWorkContext workContext
|
||||
@{
|
||||
|
||||
var simpleLMSSettings = (SimpleLMSSettings)ViewData["simpleLMSSettings"];
|
||||
|
||||
}
|
||||
|
||||
@if (Model.LessonType == LessonType.Video)
|
||||
{
|
||||
<div id="video-content">
|
||||
@if (Model.Video.VideoType == VideoType.Youtube)
|
||||
{
|
||||
<div class="video-container">
|
||||
<iframe height="400" width="100%" src="https://www.youtube.com/embed/@Model.Video.VideoIdFromProvider?autoplay=1@(!string.IsNullOrEmpty(Model.Video.TimeCode)?"&start="+Model.Video.TimeCode:"")"
|
||||
title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen>
|
||||
</iframe>
|
||||
</div>
|
||||
}
|
||||
@if (Model.Video.VideoType == VideoType.Vimeo)
|
||||
{
|
||||
<div style="padding:56.25% 0 0 0;position:relative;">
|
||||
<iframe src="https://player.vimeo.com/video/@(Model.Video.VideoIdFromProvider+(!string.IsNullOrEmpty(Model.Video.TimeCode)?"#"+Model.Video.TimeCode:"") )?autoplay=1&badge=0&autopause=0&player_id=0&byline=0&title=0@(!string.IsNullOrEmpty(simpleLMSSettings.VimeoClient)?"&app_id="+simpleLMSSettings.VimeoClient:"")'"
|
||||
frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;"></iframe>
|
||||
</div>
|
||||
<script src="https://player.vimeo.com/api/player.js"></script>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
}
|
||||
<div class="p-3 mt-3">
|
||||
@Html.Raw(Model.LessonContents)
|
||||
</div>
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
|
||||
@model CourseOverviewListModel
|
||||
|
||||
@inject CatalogSettings catalogSettings
|
||||
@inject IWorkContext workContext
|
||||
@{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@if (Model.Courses.Count() > 0)
|
||||
{
|
||||
<div class="product-grid">
|
||||
<div class="item-grid">
|
||||
@foreach (var course in Model.Courses)
|
||||
{
|
||||
<div class="item-box">
|
||||
<div class="product-item" data-productid="@course.Id">
|
||||
<div class="picture">
|
||||
<a href="@Url.Action("CoursesDetails","Customer", new { courseId = course.Id })" title="@course.ParentProductName">
|
||||
<img alt="@course.ParentProductName" src="@course.ProductMainImage" title="@course.ParentProductName" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="details">
|
||||
<h2 class="product-title">
|
||||
<a href="@Url.Action("CoursesDetails","Customer", new { courseId = course.Id })">@course.ParentProductName</a>
|
||||
</h2>
|
||||
<div class="progress"></div>
|
||||
<div class="buttons">
|
||||
<a href="@Url.Action("CoursesDetails","Customer", new { courseId = course.Id })" class="button-1">@(course.CourseProgress == 0 ? T("SimpleLMS.Start") : T("SimpleLMS.Resume"))</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
var pager = Html.Pager(Model)
|
||||
.QueryParam("page")
|
||||
.RenderEmptyParameters(true);
|
||||
|
||||
@if (!await pager.IsEmpty())
|
||||
{
|
||||
<div class="pager">`
|
||||
@pager
|
||||
</div>
|
||||
<script type="text/javascript">$(document).ready(function () {
|
||||
addPagerHandlers();
|
||||
});</script>
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
<div>@T("SimpleLMS.MyCourses.NoCoursesToShow")</div>
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@*<div class="product-item" data-productid="@Model.Id">
|
||||
<div class="picture">
|
||||
<a href="@Url.RouteUrl("Product", new { productid = Model.Id })" title="@Model.DefaultPictureModel.Title">
|
||||
<img alt="@Model.DefaultPictureModel.AlternateText" src="@Model.DefaultPictureModel.ImageUrl" title="@Model.DefaultPictureModel.Title" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="details">
|
||||
<h2 class="product-title">
|
||||
<a href="@Url.RouteUrl("CoursesDetails", new {productid = Model.Id})">@Model.Name</a>
|
||||
</h2>
|
||||
@if (catalogSettings.ShowSkuOnCatalogPages && !string.IsNullOrEmpty(Model.Sku))
|
||||
{
|
||||
<div class="sku">
|
||||
@Model.Sku
|
||||
</div>
|
||||
}
|
||||
@if (Model.ReviewOverviewModel.AllowCustomerReviews)
|
||||
{
|
||||
var ratingPercent = 0;
|
||||
if (Model.ReviewOverviewModel.TotalReviews != 0)
|
||||
{
|
||||
ratingPercent = ((Model.ReviewOverviewModel.RatingSum*100)/Model.ReviewOverviewModel.TotalReviews)/5;
|
||||
}
|
||||
<div class="product-rating-box" title="@string.Format(T("Reviews.TotalReviews").Text, Model.ReviewOverviewModel.TotalReviews)">
|
||||
<div class="rating">
|
||||
<div style="width: @(ratingPercent)%">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="description">
|
||||
@Html.Raw(Model.ShortDescription)
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>*@
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
@inherits Nop.Web.Framework.Mvc.Razor.NopRazorPage<TModel>
|
||||
|
||||
@inject INopHtmlHelper NopHtml
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@*we remove the default InputTagHelper to prevent the checkbox duplicating: https://stackoverflow.com/questions/42544961/asp-net-core-custom-input-tag-helper-rendering-duplicate-checkboxes*@
|
||||
@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.InputTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@addTagHelper *, Nop.Web.Framework
|
||||
@addTagHelper *, MiniProfiler.AspNetCore.Mvc
|
||||
|
||||
@using System.Globalization;
|
||||
@using System.Text.Encodings.Web
|
||||
@using Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||
@using Microsoft.Extensions.Primitives
|
||||
@using static Nop.Services.Common.NopLinksDefaults
|
||||
@using Nop.Web.Components
|
||||
@using Nop.Web.Extensions
|
||||
@using Nop.Web.Framework
|
||||
@using Nop.Web.Framework.Events
|
||||
@using Nop.Web.Framework.Extensions
|
||||
@using Nop.Web.Framework.Infrastructure
|
||||
@using Nop.Web.Framework.Models
|
||||
@using Nop.Web.Framework.Mvc.Routing
|
||||
@using Nop.Web.Framework.Security.Captcha
|
||||
@using Nop.Web.Framework.Security.Honeypot
|
||||
@using Nop.Web.Framework.Themes
|
||||
@using Nop.Web.Framework.UI
|
||||
@using Nop.Web.Models.Blogs
|
||||
@using Nop.Web.Models.Boards
|
||||
@using Nop.Web.Models.Catalog
|
||||
@using Nop.Web.Models.Checkout
|
||||
@using Nop.Web.Models.Cms
|
||||
@using Nop.Web.Models.Common
|
||||
@using Nop.Web.Models.Customer
|
||||
@using Nop.Web.Models.Media
|
||||
@using Nop.Web.Models.News
|
||||
@using Nop.Web.Models.Newsletter
|
||||
@using Nop.Web.Models.Order
|
||||
@using Nop.Web.Models.Polls
|
||||
@using Nop.Web.Models.PrivateMessages
|
||||
@using Nop.Web.Models.Profile
|
||||
@using Nop.Web.Models.ShoppingCart
|
||||
@using Nop.Web.Models.Topics
|
||||
@using Nop.Web.Models.Vendors
|
||||
|
||||
|
||||
@using Nop.Core
|
||||
@using Nop.Core.Domain.Catalog
|
||||
|
||||
@using Nop.Plugin.Misc.SimpleLMS.Models
|
||||
@using Nop.Plugin.Misc.SimpleLMS
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"Group": "Misc",
|
||||
"FriendlyName": "SimpleLMS",
|
||||
"SystemName": "Misc.SimpleLMS",
|
||||
"Version": "1.00",
|
||||
"SupportedVersions": [ "4.50" ],
|
||||
"Author": "www.slyko.tech",
|
||||
"DisplayOrder": 1,
|
||||
"FileName": "Nop.Plugin.Misc.SimpleLMS.dll",
|
||||
"Description": "SimpleLMS is a learning management system plugin for NopCommerce."
|
||||
}
|
||||