Resolve merge conflict in .gitignore
This commit is contained in:
commit
0eca8543a9
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,3 +1,17 @@
|
|||||||
|
/.phpunit.cache
|
||||||
|
/node_modules
|
||||||
|
/public/build
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/public/uploads/*.jpg
|
||||||
|
/public/uploads/*.png
|
||||||
|
/public/uploads/*.mp4
|
||||||
|
/public/uploads/*.jpg
|
||||||
|
/public/uploads/*.png
|
||||||
|
/public/uploads/*.mp4
|
||||||
|
/public/uploads
|
||||||
|
!/resources/views/components/home_made_by_builder
|
||||||
|
/storage/*.key
|
||||||
/vendor
|
/vendor
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
|||||||
@ -74,7 +74,7 @@ Route::name('admin.')->prefix('admin')->middleware('admin')->group(function () {
|
|||||||
Route::post('course/approval/{id}', [CourseController::class, 'approval'])->name('course.approval');
|
Route::post('course/approval/{id}', [CourseController::class, 'approval'])->name('course.approval');
|
||||||
|
|
||||||
//invoice
|
//invoice
|
||||||
Route::get('invoice/{id?}', [InvoiceController::class, 'invoice'])->name('invoice');
|
Route::get('invoice/{id?}', [InvoiceController::class, 'invoice'])->name('admin.invoice');
|
||||||
|
|
||||||
Route::controller(Updater::class)->middleware('auth', 'verified')->group(function () {
|
Route::controller(Updater::class)->middleware('auth', 'verified')->group(function () {
|
||||||
|
|
||||||
@ -464,8 +464,8 @@ Route::name('admin.')->prefix('admin')->middleware('admin')->group(function () {
|
|||||||
Route::get('knowledge-base','index')->name('knowledge.base');
|
Route::get('knowledge-base','index')->name('knowledge.base');
|
||||||
Route::post('knowledge-base/store','store')->name('knowledge.base.store');
|
Route::post('knowledge-base/store','store')->name('knowledge.base.store');
|
||||||
Route::get('knowledge-base/single-post/{id}','show')->name('knowledge.base.show');
|
Route::get('knowledge-base/single-post/{id}','show')->name('knowledge.base.show');
|
||||||
Route::get('knowledge-base/edit-post/{id}','edit')->name('knowledge.base.edit');
|
Route::get('knowledge-base/edit-post/{id}','edit')->name('knowledge.base.edit');
|
||||||
Route::post('knowledge-base/update-post/{id}','update')->name('knowledge.base.update');
|
Route::post('knowledge-base/update-post/{id}','update')->name('knowledge.base.update');
|
||||||
Route::get('knowledge-base/delete/{id}','destroy')->name('knowledge.base.delete');
|
Route::get('knowledge-base/delete/{id}','destroy')->name('knowledge.base.delete');
|
||||||
Route::get('knowledge-base/post/{id}','post')->name('knowledge.base.post');
|
Route::get('knowledge-base/post/{id}','post')->name('knowledge.base.post');
|
||||||
|
|
||||||
|
|||||||
@ -10,5 +10,5 @@ Route::controller(CourseController::class)->group(function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Route::controller(MycourseController::class)->middleware('auth')->group(function () {
|
Route::controller(MycourseController::class)->middleware('auth')->group(function () {
|
||||||
Route::get('Invoice/{id}', 'invoice')->name('invoice');
|
Route::get('Invoice/{id}', 'invoice')->name('custom.invoice');
|
||||||
});
|
});
|
||||||
|
|||||||
@ -53,7 +53,7 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
Route::get('purchase/course/{course_id}', 'purchase_course')->name('purchase.course');
|
Route::get('purchase/course/{course_id}', 'purchase_course')->name('purchase.course');
|
||||||
Route::post('payout', 'payout')->name('payout');
|
Route::post('payout', 'payout')->name('payout');
|
||||||
Route::get('purchase-history', 'purchase_history')->name('purchase.history');
|
Route::get('purchase-history', 'purchase_history')->name('purchase.history');
|
||||||
Route::get('invoice/{id}', 'invoice')->name('invoice');
|
Route::get('invoice/{id}', 'invoice')->name('student.invoice');
|
||||||
});
|
});
|
||||||
|
|
||||||
// cart routes
|
// cart routes
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,125 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\admin;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Models\Knowledge_base;
|
|
||||||
use App\Models\Knowledge_base_topick;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class ArticleController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for creating a new resource.
|
|
||||||
*/
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'title' => 'required | max:200',
|
|
||||||
'description'=> 'required'
|
|
||||||
]);
|
|
||||||
$article = new Knowledge_base_topick;
|
|
||||||
$article->topic_name = $request->title;
|
|
||||||
$article->description = $request->description;
|
|
||||||
$article->knowledge_base_id = $request->topick_id;
|
|
||||||
$done = $article->save();
|
|
||||||
if ($done) {
|
|
||||||
return redirect()->route('admin.articles',['id'=> $request->topick_id])->with('success', get_phrase('article saved.'));
|
|
||||||
} else {
|
|
||||||
return redirect()->route('admin.articles',['id'=> $request->topick_id])->with('error', get_phrase('article not saved.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(string $id)
|
|
||||||
{
|
|
||||||
$articleTitle = Knowledge_base::where('id', $id)->first();
|
|
||||||
if (!$articleTitle) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
$articles = Knowledge_base_topick::where('knowledge_base_id', $id)->orderBy('updated_at', 'desc')->paginate(10);
|
|
||||||
|
|
||||||
|
|
||||||
return view("admin.articles.index" , ["articleTitle"=> $articleTitle], ['articles'=> $articles]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*/
|
|
||||||
public function edit(string $id)
|
|
||||||
{
|
|
||||||
$articleTitle = Knowledge_base::where('id', $id)->first();
|
|
||||||
if (!$articleTitle) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
return view('admin.articles.create', ['articleTitle'=>$articleTitle]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
|
||||||
|
|
||||||
$article = Knowledge_base_topick::where('id', $id)->first();
|
|
||||||
if (!$article) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$knowledgeBaseId = $article->knowledge_base_id;
|
|
||||||
$article->topic_name = $request->topic_name;
|
|
||||||
$article->description = $request->description;
|
|
||||||
$done = $article->update();
|
|
||||||
if ($done) {
|
|
||||||
return redirect()->route('admin.articles',['id'=> $knowledgeBaseId])->with('success', get_phrase('successfully updated.'));
|
|
||||||
} else {
|
|
||||||
return redirect()->route('admin.articles',['id'=> $knowledgeBaseId])->with('error', get_phrase('not updated.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
$article = Knowledge_base_topick::where('id', $id)->first();
|
|
||||||
|
|
||||||
if (!$article) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$knowledgeBaseId = $article->knowledge_base_id;
|
|
||||||
$done = $article->delete();
|
|
||||||
if ($done) {
|
|
||||||
return redirect()->route('admin.articles', ['id'=> $knowledgeBaseId])->with('success', get_phrase('article deleted'));
|
|
||||||
} else {
|
|
||||||
return redirect()->route('admin.articles', ['id'=> $knowledgeBaseId])->with('error', get_phrase('article not deleted'));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,261 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Controllers\ZoomMeetingController;
|
|
||||||
use App\Models\BootcampLiveClass;
|
|
||||||
use App\Models\BootcampModule;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class BootcampLiveClassController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
date_default_timezone_set('Asia/Dhaka');
|
|
||||||
}
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'date' => 'required|date',
|
|
||||||
'start_time' => 'required|string',
|
|
||||||
'end_time' => 'required|string|after:start_time',
|
|
||||||
'module_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check selected module
|
|
||||||
$module = BootcampModule::where('id', $request->module_id)->first();
|
|
||||||
if (! $module) {
|
|
||||||
Session::flash('error', get_phrase('Module does not exist.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// process class schedule
|
|
||||||
$start = $request->date . ' ' . $request->start_time;
|
|
||||||
$start_timestamp = strtotime($start);
|
|
||||||
$end = $request->date . ' ' . $request->end_time;
|
|
||||||
$end_timestamp = strtotime($end);
|
|
||||||
|
|
||||||
// check module and class schedule
|
|
||||||
if ($module->restriction) {
|
|
||||||
if ($module->restriction == 1 && $start_timestamp < $module->publish_date) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
if ($module->restriction == 2 && (($start_timestamp < $module->publish_date || $start_timestamp > $module->expiry_date) && ($end_timestamp < $module->publish_date || $end_timestamp > $module->expiry_date))) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check duplicate title for same bootcamp id
|
|
||||||
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_modules.id', $request->module_id)
|
|
||||||
->where('bootcamp_live_classes.title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['module_id'] = $request->module_id;
|
|
||||||
$data['start_time'] = $start_timestamp;
|
|
||||||
$data['end_time'] = $end_timestamp;
|
|
||||||
|
|
||||||
// Calculate the difference in seconds
|
|
||||||
$difference_in_seconds = $data['end_time'] - $data['start_time'];
|
|
||||||
|
|
||||||
// Convert the difference to minutes
|
|
||||||
$difference_in_minutes = $difference_in_seconds / 60;
|
|
||||||
|
|
||||||
$joiningData = ZoomMeetingController::createMeeting($request->title, $start_timestamp, $difference_in_minutes);
|
|
||||||
$joiningInfoArr = json_decode($joiningData, true);
|
|
||||||
|
|
||||||
if (array_key_exists('code', $joiningInfoArr) && $joiningInfoArr) {
|
|
||||||
return redirect(route('admin.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']))->with('error', get_phrase($joiningInfoArr['message']));
|
|
||||||
}
|
|
||||||
$data['provider'] = 'zoom';
|
|
||||||
$data['joining_data'] = $joiningData;
|
|
||||||
|
|
||||||
BootcampLiveClass::insert($data);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Live class has been created.'));
|
|
||||||
return redirect()->route('admin.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'start_time' => 'required',
|
|
||||||
'end_time' => 'required',
|
|
||||||
'module_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamp_live_classes.module_id', $request->module_id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamp_modules.restriction', 'bootcamp_modules.publish_date', 'bootcamp_modules.expiry_date')
|
|
||||||
->first();
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// process class schedule
|
|
||||||
$start = $request->date . ' ' . $request->start_time;
|
|
||||||
$start_timestamp = strtotime($start);
|
|
||||||
$end = $request->date . ' ' . $request->end_time;
|
|
||||||
$end_timestamp = strtotime($end);
|
|
||||||
|
|
||||||
// check module and class schedule
|
|
||||||
if ($class->restriction) {
|
|
||||||
if ($class->restriction == 1 && $start_timestamp < $class->publish_date) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
if ($class->restriction == 2 && (($start_timestamp < $class->publish_date || $start_timestamp > $class->expiry_date) && ($end_timestamp < $class->publish_date || $end_timestamp > $class->expiry_date))) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check duplicate title for same bootcamp id
|
|
||||||
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_modules.id', $request->module_id)
|
|
||||||
->where('bootcamp_live_classes.id', '!=', $id)
|
|
||||||
->where('bootcamp_live_classes.title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($class->start_time != $start_timestamp || $class->end_time != $end_timestamp) {
|
|
||||||
$data['force_stop'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['module_id'] = $request->module_id;
|
|
||||||
$data['start_time'] = $start_timestamp;
|
|
||||||
$data['end_time'] = $end_timestamp;
|
|
||||||
|
|
||||||
if ($class->provider == 'zoom') {
|
|
||||||
$oldMeetingData = json_decode($class->joining_data, true);
|
|
||||||
ZoomMeetingController::updateMeeting($request->title, $request->start_time, $oldMeetingData['id']);
|
|
||||||
$oldMeetingData["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->start_time));
|
|
||||||
$oldMeetingData["topic"] = $request->class_topic;
|
|
||||||
$data['joining_data'] = json_encode($oldMeetingData);
|
|
||||||
}
|
|
||||||
|
|
||||||
$class->update($data);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Live class has been updated.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)->first();
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$oldMeetingData = json_decode($class->joining_data, true);
|
|
||||||
ZoomMeetingController::deleteMeeting($oldMeetingData['id']);
|
|
||||||
$class->delete();
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Live class has been deleted.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function join_class($slug)
|
|
||||||
{
|
|
||||||
$current_time = time();
|
|
||||||
$extended_time = $current_time + (60 * 15);
|
|
||||||
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.slug', $slug)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id', 'bootcamps.user_id as host_id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Class not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
$page_data['class'] = $class;
|
|
||||||
$page_data['user'] = get_user_info($class->host_id);
|
|
||||||
$page_data['is_host'] = 1;
|
|
||||||
return view('bootcamp_online_class.index', $page_data);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($class->joining_data, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop_class($id)
|
|
||||||
{
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$class->update(['force_stop' => 1]);
|
|
||||||
Session::flash('success', get_phrase('Class has been ended.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sort(Request $request)
|
|
||||||
{
|
|
||||||
$classes = json_decode($request->itemJSON);
|
|
||||||
foreach ($classes as $key => $value) {
|
|
||||||
$updater = $key + 1;
|
|
||||||
BootcampLiveClass::where('id', $value)->update(['sort' => $updater]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'status' => true,
|
|
||||||
'success' => get_phrase('Classes sorted successfully'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\admin;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use App\Models\Knowledge_base;
|
|
||||||
use App\Models\Knowledge_base_topick;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
|
|
||||||
class KnowledgeBaseController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$datas = Knowledge_base::orderBy("created_at","desc")->paginate(10);
|
|
||||||
|
|
||||||
return view('admin.knowledge_base.index', compact('datas'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for creating a new resource.
|
|
||||||
*/
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$request->validate([
|
|
||||||
'title' => 'required | max:200 '
|
|
||||||
]);
|
|
||||||
|
|
||||||
$query = new Knowledge_base;
|
|
||||||
$query->title = $request->title;
|
|
||||||
$done = $query->save();
|
|
||||||
if ($done) {
|
|
||||||
return redirect()->back()->with('success', get_phrase('successfullly added'));
|
|
||||||
} else {
|
|
||||||
return redirect()->back()->with('error', get_phrase('something wrong!'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(string $id)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*/
|
|
||||||
public function edit(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'title' => 'required | max:200 '
|
|
||||||
]);
|
|
||||||
|
|
||||||
$query = Knowledge_base::where('id', $id)->first();
|
|
||||||
$query->title = $request->title;
|
|
||||||
$done = $query->update();
|
|
||||||
|
|
||||||
if ($done) {
|
|
||||||
return redirect()->back()->with('success', get_phrase('updated successfully.'));
|
|
||||||
} else {
|
|
||||||
return redirect()->back()->with('error', get_phrase('no data found'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
$done = Knowledge_base_topick::where('knowledge_base_id', $id)->delete();
|
|
||||||
$ok = Knowledge_base::where('id', $id)->delete();
|
|
||||||
|
|
||||||
if ($done || $ok) {
|
|
||||||
return redirect()->back()->with('success', get_phrase('successfully deleted.'));
|
|
||||||
} else {
|
|
||||||
return redirect()->back()->with('error', get_phrase('something went wrong.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,218 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Bootcamp;
|
|
||||||
use App\Models\BootcampPurchase;
|
|
||||||
use App\Models\CartItem;
|
|
||||||
use App\Models\Coupon;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Enrollment;
|
|
||||||
use App\Models\OfflinePayment;
|
|
||||||
use App\Models\Payment_history;
|
|
||||||
use App\Models\TeamPackagePurchase;
|
|
||||||
use App\Models\TeamTrainingPackage;
|
|
||||||
use App\Models\TutorBooking;
|
|
||||||
use App\Models\TutorSchedule;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Response;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class OfflinePaymentController extends Controller
|
|
||||||
{
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
$payments = OfflinePayment::orderBY('id', 'DESC');
|
|
||||||
|
|
||||||
if ($request->status == 'approved') {
|
|
||||||
$payments->where('status', 1);
|
|
||||||
} elseif ($request->status == 'suspended') {
|
|
||||||
$payments->where('status', 2);
|
|
||||||
} elseif ($request->status == 'pending') {
|
|
||||||
$payments->where('status', 0)->orWhere('status', null);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['payments'] = $payments->paginate(10);
|
|
||||||
return view('admin.offline_payments.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function download_doc($id)
|
|
||||||
{
|
|
||||||
// validate id
|
|
||||||
if (empty($id)) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// payment details
|
|
||||||
$payment_details = OfflinePayment::where('id', $id)->first();
|
|
||||||
$filePath = public_path($payment_details->doc);
|
|
||||||
if (! file_exists($filePath)) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
// download file
|
|
||||||
return Response::download($filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function accept_payment($id)
|
|
||||||
{
|
|
||||||
// validate id
|
|
||||||
if (empty($id)) {
|
|
||||||
Session::flash('error', get_phrase('Id can not be empty.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// payment details
|
|
||||||
$query = OfflinePayment::where('id', $id)->where('status', 0);
|
|
||||||
if ($query->doesntExist()) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$payment_details = $query->first();
|
|
||||||
|
|
||||||
$payment['invoice'] = Str::random(20);
|
|
||||||
$payment['user_id'] = $payment_details['user_id'];
|
|
||||||
$payment['payment_type'] = 'offline';
|
|
||||||
$payment['coupon'] = $payment_details->coupon;
|
|
||||||
|
|
||||||
if ($payment_details->item_type == 'course') {
|
|
||||||
$items = json_decode($payment_details->items);
|
|
||||||
|
|
||||||
foreach ($items as $item) {
|
|
||||||
$course = Course::where('id', $item)->first();
|
|
||||||
$payment['course_id'] = $course->id;
|
|
||||||
|
|
||||||
// Calculate base amount
|
|
||||||
$amount = $course->discount_flag == 1 ? $course->discounted_price : $course->price;
|
|
||||||
|
|
||||||
// Apply coupon discount if applicable
|
|
||||||
$discounted_price = 0;
|
|
||||||
if ($payment_details->coupon) {
|
|
||||||
$coupon = Coupon::where('code', $payment_details->coupon)->first();
|
|
||||||
if ($coupon) {
|
|
||||||
$discounted_price = $amount * ($coupon->discount / 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Final payment amount and tax
|
|
||||||
$final_amount = $amount - $discounted_price;
|
|
||||||
$payment['amount'] = $final_amount;
|
|
||||||
$payment['tax'] = (get_settings('course_selling_tax') / 100) * $final_amount;
|
|
||||||
|
|
||||||
// Calculate admin and instructor revenue
|
|
||||||
if (get_course_creator_id($course->id)->role == 'admin') {
|
|
||||||
$payment['admin_revenue'] = $final_amount;
|
|
||||||
} else {
|
|
||||||
$payment['instructor_revenue'] = $final_amount * (get_settings('instructor_revenue') / 100);
|
|
||||||
$payment['admin_revenue'] = $final_amount - $payment['instructor_revenue'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert payment record
|
|
||||||
$accept_payment = Payment_history::insert($payment);
|
|
||||||
|
|
||||||
// Enroll user in course if payment succeeds
|
|
||||||
if ($accept_payment) {
|
|
||||||
|
|
||||||
$enroll['user_id'] = $payment_details['user_id'];
|
|
||||||
$enroll['course_id'] = $course->id;
|
|
||||||
$enroll['enrollment_type'] = "paid";
|
|
||||||
$enroll['entry_date'] = time();
|
|
||||||
$enroll['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$enroll['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
if ($course->expiry_period > 0) {
|
|
||||||
$days = $course->expiry_period * 30;
|
|
||||||
$enroll['expiry_date'] = strtotime("+" . $days . " days");
|
|
||||||
} else {
|
|
||||||
$enroll['expiry_date'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Enrollment::insert($enroll);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} elseif ($payment_details->item_type == 'bootcamp') {
|
|
||||||
$bootcamps = Bootcamp::whereIn('id', json_decode($payment_details->items, true))->get();
|
|
||||||
foreach($bootcamps as $bootcamp){
|
|
||||||
$bootcamp_payment['invoice'] = '#' . Str::random(20);
|
|
||||||
$bootcamp_payment['user_id'] = $payment_details['user_id'];
|
|
||||||
$bootcamp_payment['bootcamp_id'] = $bootcamp->id;
|
|
||||||
$bootcamp_payment['price'] = $bootcamp->discount_flag == 1 ? $bootcamp->price - $bootcamp->discounted_price : $bootcamp->price;
|
|
||||||
$bootcamp_payment['tax'] = 0;
|
|
||||||
$bootcamp_payment['payment_method'] = 'offline';
|
|
||||||
$bootcamp_payment['status'] = 1;
|
|
||||||
|
|
||||||
// insert bootcamp purchase
|
|
||||||
BootcampPurchase::insert($bootcamp_payment);
|
|
||||||
}
|
|
||||||
} elseif ($payment_details->item_type == 'package') {
|
|
||||||
$packages = TeamTrainingPackage::whereIn('id', json_decode($payment_details->items, true))->get();
|
|
||||||
foreach($packages as $package){
|
|
||||||
$package_payment['invoice'] = '#' . Str::random(20);
|
|
||||||
$package_payment['user_id'] = $payment_details['user_id'];
|
|
||||||
$package_payment['package_id'] = $package->id;
|
|
||||||
$package_payment['price'] = $package->price;
|
|
||||||
$package_payment['tax'] = 0;
|
|
||||||
$package_payment['payment_method'] = 'offline';
|
|
||||||
$package_payment['status'] = 1;
|
|
||||||
|
|
||||||
// insert package purchase
|
|
||||||
TeamPackagePurchase::insert($package_payment);
|
|
||||||
}
|
|
||||||
} elseif ($payment_details->item_type == 'tutor_booking') {
|
|
||||||
$schedules = TutorSchedule::whereIn('id', json_decode($payment_details->items, true))->get();
|
|
||||||
foreach($schedules as $schedule){
|
|
||||||
|
|
||||||
$schedule_payment['invoice'] = '#' . Str::random(20);
|
|
||||||
$schedule_payment['student_id'] = $payment_details['user_id'];
|
|
||||||
$schedule_payment['schedule_id'] = $schedule->id;
|
|
||||||
$schedule_payment['price'] = $payment_details['total_amount'];
|
|
||||||
$schedule_payment['tax'] = $payment_details['tax'];
|
|
||||||
$schedule_payment['payment_method'] = 'offline';
|
|
||||||
|
|
||||||
$schedule = TutorSchedule::find($schedule->id);
|
|
||||||
if (get_user_info($schedule->tutor_id)->role == 'admin') {
|
|
||||||
$schedule_payment['admin_revenue'] = $payment_details['payable_amount'];
|
|
||||||
} else {
|
|
||||||
$schedule_payment['instructor_revenue'] = $payment_details['total_amount'] * (get_settings('instructor_revenue') / 100);
|
|
||||||
$schedule_payment['admin_revenue'] = $payment_details['total_amount'] - $schedule_payment['instructor_revenue'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$schedule_payment['tutor_id'] = $schedule->tutor_id;
|
|
||||||
$schedule_payment['start_time'] = $schedule->start_time;
|
|
||||||
$schedule_payment['end_time'] = $schedule->end_time;
|
|
||||||
|
|
||||||
// insert tutor bookings
|
|
||||||
TutorBooking::insert($schedule_payment);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove items from offline payment
|
|
||||||
OfflinePayment::where('id', $id)->update(['status' => 1]);
|
|
||||||
|
|
||||||
// go back
|
|
||||||
Session::flash('success', 'Payment has been accepted.');
|
|
||||||
return redirect()->route('admin.offline.payments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function decline_payment($id)
|
|
||||||
{
|
|
||||||
// remove items from offline payment
|
|
||||||
OfflinePayment::where('id', $id)->update(['status' => 2]);
|
|
||||||
|
|
||||||
// go back
|
|
||||||
Session::flash('success', 'Payment has been suspended');
|
|
||||||
return redirect()->route('admin.offline.payments');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete_payment($id)
|
|
||||||
{
|
|
||||||
OfflinePayment::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Admin revenue delete successfully'));
|
|
||||||
return redirect()->route('admin.offline.payments');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Builder_page;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\FrontendSetting;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class PageBuilderController extends Controller
|
|
||||||
{
|
|
||||||
function page_list()
|
|
||||||
{
|
|
||||||
return view('admin.page_builder.page_list');
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_store(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required'
|
|
||||||
]);
|
|
||||||
|
|
||||||
Builder_page::insert(['name' => $request->name, 'created_at' => date('Y-m-d H:i:s')]);
|
|
||||||
return redirect(route('admin.pages'))->with('success', get_phrase('New home page layout has been added'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required'
|
|
||||||
]);
|
|
||||||
|
|
||||||
Builder_page::where('id', $id)->update(['name' => $request->name, 'updated_at' => date('Y-m-d H:i:s')]);
|
|
||||||
return redirect(route('admin.pages'))->with('success', get_phrase('Home page name has been updated'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_delete($id)
|
|
||||||
{
|
|
||||||
Builder_page::where('id', $id)->delete();
|
|
||||||
return redirect(route('admin.pages'))->with('success', get_phrase('The page name has been updated'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_status($id)
|
|
||||||
{
|
|
||||||
$query = Builder_page::where('id', $id);
|
|
||||||
if ($query->first()->status == 1) {
|
|
||||||
$query->update(['status' => 0]);
|
|
||||||
$response = [
|
|
||||||
'success' => get_phrase('Home page deactivated')
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
FrontendSetting::where('key', 'home_page')->update(['value' => $query->first()->identifier]);
|
|
||||||
$query->update(['status' => 1]);
|
|
||||||
$response = [
|
|
||||||
'success' => get_phrase('Home page activated')
|
|
||||||
];
|
|
||||||
}
|
|
||||||
Builder_page::where('id', '!=', $id)->update(['status' => 0]);
|
|
||||||
|
|
||||||
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_layout_edit($id)
|
|
||||||
{
|
|
||||||
return view('admin.page_builder.page_layout_edit', ['id' => $id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_layout_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'developer_elements' => 'required',
|
|
||||||
'builder_elements' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$built_file_names = [];
|
|
||||||
foreach($request->builder_elements as $file_name => $builder_elements){
|
|
||||||
$built_file_names[] = $file_name;
|
|
||||||
$developer_file_content = file_get_contents(base_path('resources/views/components/home_made_by_developer/'.$file_name.'.blade.php'));
|
|
||||||
$developer_file_content = $this->replace_special_character($developer_file_content);
|
|
||||||
|
|
||||||
foreach($builder_elements as $key => $builder_element){
|
|
||||||
$developer_element = $request->developer_elements[$file_name][$key];
|
|
||||||
|
|
||||||
if($builder_element['tag'] == 'img'){
|
|
||||||
$builder_element_src = explode('/public/', $builder_element['src']);
|
|
||||||
|
|
||||||
if(array_key_exists(1, $builder_element_src)){
|
|
||||||
$updated_url_from_builder = "{{asset('".$builder_element_src[1]."')}}";
|
|
||||||
}else{
|
|
||||||
$updated_url_from_builder = "{{asset('".$builder_element['src']."')}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
$prepared_single_element = str_replace($developer_element['src'], $updated_url_from_builder, $developer_element['element']);
|
|
||||||
$developer_file_content = str_replace($developer_element['element'], $prepared_single_element, $developer_file_content);
|
|
||||||
}elseif($builder_element['tag'] != 'null'){
|
|
||||||
$developer_element_tag = $this->replace_special_character($developer_element['element']);
|
|
||||||
$developer_element_content = $this->replace_special_character($developer_element['content']);
|
|
||||||
|
|
||||||
$prepared_single_element = str_replace($developer_element_content, '{{ get_phrase("'.$builder_element['content'].'") }}', $developer_element_tag);
|
|
||||||
$prepared_single_element = str_replace('(""', '("', $prepared_single_element);
|
|
||||||
$prepared_single_element = str_replace('"")', '")', $prepared_single_element);
|
|
||||||
$developer_file_content = str_replace($developer_element_tag, $prepared_single_element, $developer_file_content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
file_put_contents(base_path("resources/views/components/home_made_by_builder/".$file_name.'.blade.php'), $developer_file_content);
|
|
||||||
}
|
|
||||||
Builder_page::where('id', $id)->update(['html' => json_encode($built_file_names)]);
|
|
||||||
return redirect(route('admin.pages'))->with('success', get_phrase('Page layout has been updated'));
|
|
||||||
}
|
|
||||||
|
|
||||||
function replace_special_character($text){
|
|
||||||
if($text){
|
|
||||||
$text = str_replace('&', '&', $text);
|
|
||||||
}
|
|
||||||
return $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
function replace_builder_content($html_1 = "", $html_2 = "")
|
|
||||||
{
|
|
||||||
//REPLACE $html_1 BY $html_2
|
|
||||||
|
|
||||||
// Extract src and builder-identity attributes from html_2
|
|
||||||
preg_match_all('/<img\s+class="builder-editable"\s+builder-identity="(\d+)"\s+src="([^"]+)"/', $html_2, $matches2, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
// Create an associative array to map builder-identity to src
|
|
||||||
$srcMap = [];
|
|
||||||
foreach ($matches2 as $match) {
|
|
||||||
$srcMap[$match[1]] = $match[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace src attributes in html_1 using the srcMap
|
|
||||||
$html_1 = preg_replace_callback('/<img\s+class="builder-editable"\s+builder-identity="(\d+)"\s+src="([^"]+)"/', function ($matches) use ($srcMap) {
|
|
||||||
$identity = $matches[1];
|
|
||||||
if (isset($srcMap[$identity])) {
|
|
||||||
return '<img class="builder-editable" builder-identity="' . $identity . '" src="{{asset("' . $srcMap[$identity] . '")}}"';
|
|
||||||
}
|
|
||||||
return $matches[0];
|
|
||||||
}, $html_1);
|
|
||||||
|
|
||||||
// Extract content and builder-identity attributes from html_2 (excluding img tags)
|
|
||||||
preg_match_all('/<([^img][^>]*)builder-identity="(\d+)"[^>]*>(.*?)<\/[^>]+>/', $html_2, $matches2, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
// Create an associative array to map builder-identity to content
|
|
||||||
$contentMap = [];
|
|
||||||
foreach ($matches2 as $match) {
|
|
||||||
$contentMap[$match[2]] = $match[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace content in html_1 using the contentMap
|
|
||||||
$html_1 = preg_replace_callback('/<([^img][^>]*)builder-identity="(\d+)"[^>]*>(.*?)<\/[^>]+>/', function ($matches) use ($contentMap) {
|
|
||||||
$identity = $matches[2];
|
|
||||||
if (isset($contentMap[$identity])) {
|
|
||||||
return '<' . $matches[1] . 'builder-identity="' . $identity . '">' . $contentMap[$identity] . '<' . substr(strrchr($matches[0], '<'), 1);
|
|
||||||
}
|
|
||||||
return $matches[0];
|
|
||||||
}, $html_1);
|
|
||||||
|
|
||||||
return $html_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function find_builder_block_elements($html)
|
|
||||||
{
|
|
||||||
// Define a regex pattern to match all divs with builder-block-file-name attribute
|
|
||||||
$pattern = '/<div\s+[^>]*builder-block-file-name="([^"]+)"[^>]*>(.*?)<\/div>/s';
|
|
||||||
|
|
||||||
// Use preg_match_all to find all matches
|
|
||||||
preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
|
|
||||||
|
|
||||||
// Collect the file name and HTML content inside each matched element
|
|
||||||
$elements = [];
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
$elements[] = [
|
|
||||||
'file_name' => $match[1], // The value of the builder-block-file-name attribute
|
|
||||||
'content' => $match[2] // The inner HTML content of the div
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $elements;
|
|
||||||
}
|
|
||||||
|
|
||||||
function developer_file_content(){
|
|
||||||
//return developer file content
|
|
||||||
$developer_file_content = '';
|
|
||||||
$files = array_diff(scandir(base_path('resources/views/components/home_made_by_developer')), array('.', '..'));
|
|
||||||
foreach ($files as $file){
|
|
||||||
$file_name = str_replace('.blade.php', '', $file);
|
|
||||||
$developer_file_content .= '<div builder-block-file-name="'.$file_name.'">'.file_get_contents(base_path('resources/views/components/home_made_by_developer/'.$file)).'</div>';
|
|
||||||
}
|
|
||||||
return $developer_file_content;
|
|
||||||
}
|
|
||||||
|
|
||||||
function page_layout_image_update(Request $request)
|
|
||||||
{
|
|
||||||
$remove_file_arr = explode('/', $request->remove_file);
|
|
||||||
$previous_image_path = 'uploads/home-page-builder/' . end($remove_file_arr);
|
|
||||||
remove_file($previous_image_path);
|
|
||||||
|
|
||||||
$image_path = FileUploader::upload($request->file, 'uploads/home-page-builder');
|
|
||||||
return get_image($image_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function preview($page_id)
|
|
||||||
{
|
|
||||||
$page_data['page_id'] = $page_id;
|
|
||||||
return view('frontend.default.home.preview', $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Auth;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Application;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Providers\RouteServiceProvider;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Auth\Events\Registered;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Validation\Rules;
|
|
||||||
use Illuminate\View\View;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
|
|
||||||
class RegisteredUserController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Display the registration view.
|
|
||||||
*/
|
|
||||||
public function create(): View
|
|
||||||
{
|
|
||||||
return view('auth.register');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle an incoming registration request.
|
|
||||||
*
|
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
|
||||||
*/
|
|
||||||
public function store(Request $request): RedirectResponse
|
|
||||||
{
|
|
||||||
$input = $request->all();
|
|
||||||
|
|
||||||
if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
|
|
||||||
|
|
||||||
Session::flash('error', get_phrase('Recaptcha verification failed'));
|
|
||||||
|
|
||||||
return redirect(route('register.form'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'name' => ['required', 'string', 'max:255'],
|
|
||||||
'email' => ['required', 'string', 'email', 'unique:users,email'],
|
|
||||||
'password' => ['required', Rules\Password::defaults()],
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_data = [
|
|
||||||
'name' => $request->name,
|
|
||||||
'email' => $request->email,
|
|
||||||
'role' => 'student',
|
|
||||||
'status' => 1,
|
|
||||||
'password' => Hash::make($request->password),
|
|
||||||
];
|
|
||||||
|
|
||||||
if (get_settings('student_email_verification') != 1) {
|
|
||||||
$user_data['email_verified_at'] = Carbon::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::create($user_data);
|
|
||||||
|
|
||||||
|
|
||||||
event(new Registered($user));
|
|
||||||
|
|
||||||
Auth::login($user);
|
|
||||||
|
|
||||||
// If applying as an instructor, process the application
|
|
||||||
if ($request->has('instructor')) {
|
|
||||||
|
|
||||||
// Check if application already exists
|
|
||||||
if (Application::where('user_id', $user->id)->exists()) {
|
|
||||||
Session::flash('error', get_phrase('Your request is in process. Please wait for admin to respond.'));
|
|
||||||
return redirect()->route('become.instructor');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process instructor application
|
|
||||||
$application['user_id'] = $user->id;
|
|
||||||
$application['phone'] = $request->phone;
|
|
||||||
$application['description'] = $request->description;
|
|
||||||
|
|
||||||
// Upload document
|
|
||||||
$doc = $request->file('document');
|
|
||||||
$application['document'] = 'uploads/applications/' . $user->id . Str::random(20) . '.' . $doc->extension();
|
|
||||||
|
|
||||||
FileUploader::upload($doc, $application['document'], null, null, 300);
|
|
||||||
|
|
||||||
// Store application
|
|
||||||
Application::insert($application);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Your application has been submitted.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(RouteServiceProvider::HOME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use DateInterval;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class CommonController extends Controller
|
|
||||||
{
|
|
||||||
// Get video details new code
|
|
||||||
function get_video_details(Request $request, $url = "")
|
|
||||||
{
|
|
||||||
if ($url == "") {
|
|
||||||
$url = $request->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
$host = explode('.', str_replace('www.', '', strtolower(parse_url($url, PHP_URL_HOST))));
|
|
||||||
$host = isset($host[0]) ? $host[0] : $host;
|
|
||||||
|
|
||||||
$vimeo_api_key = get_settings('vimeo_api_key');
|
|
||||||
$youtube_api_key = get_settings('youtube_api_key');
|
|
||||||
|
|
||||||
if ($host == 'vimeo') {
|
|
||||||
$video_id = substr(parse_url($url, PHP_URL_PATH), 1);
|
|
||||||
$options = array('http' => array(
|
|
||||||
'method' => 'GET',
|
|
||||||
'header' => 'Authorization: Bearer ' . $vimeo_api_key
|
|
||||||
));
|
|
||||||
$context = stream_context_create($options);
|
|
||||||
|
|
||||||
try {
|
|
||||||
$hash = json_decode(file_get_contents("https://api.vimeo.com/videos/{$video_id}", false, $context));
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
$hash = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hash == '') return;
|
|
||||||
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'provider' => 'Vimeo',
|
|
||||||
'video_id' => $video_id,
|
|
||||||
'title' => $hash->name,
|
|
||||||
'thumbnail' => $hash->pictures->sizes[0]->link,
|
|
||||||
'video' => $hash->link,
|
|
||||||
'embed_video' => "https://player.vimeo.com/video/" . $video_id,
|
|
||||||
'duration' => gmdate("H:i:s", $hash->duration)
|
|
||||||
);
|
|
||||||
} elseif ($host == 'youtube' || $host == 'youtu') {
|
|
||||||
preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', $url, $match);
|
|
||||||
$video_id = $match[1];
|
|
||||||
|
|
||||||
try {
|
|
||||||
$hash = json_decode(file_get_contents("https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&id=$video_id&key=$youtube_api_key"));
|
|
||||||
} catch (\Throwable $th) {
|
|
||||||
$hash = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($hash == '') return;
|
|
||||||
|
|
||||||
$duration = new DateInterval($hash->items[0]->contentDetails->duration);
|
|
||||||
return array(
|
|
||||||
'provider' => 'YouTube',
|
|
||||||
'video_id' => $video_id,
|
|
||||||
'title' => $hash->items[0]->snippet->title,
|
|
||||||
'thumbnail' => 'https://i.ytimg.com/vi/' . $hash->items[0]->id . '/default.jpg',
|
|
||||||
'video' => "http://www.youtube.com/watch?v=" . $hash->items[0]->id,
|
|
||||||
'embed_video' => "http://www.youtube.com/embed/" . $hash->items[0]->id,
|
|
||||||
'duration' => $duration->format('%H:%I:%S'),
|
|
||||||
);
|
|
||||||
} elseif ($host == 'drive') {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function rendered_view(Request $request, $path = "")
|
|
||||||
{
|
|
||||||
$page_data = array();
|
|
||||||
foreach ($request->all() as $key => $value) :
|
|
||||||
$page_data[$key] = $value;
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
return view($path, $page_data)->render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Mail\Mailer;
|
|
||||||
use App\Models\Contact;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class ContactController extends Controller
|
|
||||||
{
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
Contact::where('has_read', null)->update(['has_read' => 1]);
|
|
||||||
|
|
||||||
if($request->search){
|
|
||||||
$contact = Contact::where('email', 'like', "%$request->search%")
|
|
||||||
->orWhere('address', 'like', "%$request->search%")
|
|
||||||
->orWhere('phone', 'like', "%$request->search%")
|
|
||||||
->orWhere('message', 'like', "%$request->search%")
|
|
||||||
->orWhere('name', 'like', "%$request->search%")->paginate(20);
|
|
||||||
}else{
|
|
||||||
$contact = Contact::paginate(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['contacts'] = $contact;
|
|
||||||
return view('admin.contact.index', $page_data);
|
|
||||||
}
|
|
||||||
public function contact_delete($id)
|
|
||||||
{
|
|
||||||
Contact::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Contact delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function reply(Request $request)
|
|
||||||
{
|
|
||||||
$email = Contact::where('id', $request->send_to)->first();
|
|
||||||
//$this->send_mail($email->email, $request->subject, $request->reply_message);
|
|
||||||
Mail::raw($request->reply_message, function ($message) use ($email, $request){
|
|
||||||
$message->to($email->email)
|
|
||||||
->subject(get_settings('system_title'));
|
|
||||||
});
|
|
||||||
|
|
||||||
$data['replied'] = 1;
|
|
||||||
$email = Contact::where('id', $request->send_to)->update($data);
|
|
||||||
Session::flash('success', get_phrase('Email sent successfully'));
|
|
||||||
return redirect()->route('admin.contacts');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function send_mail($user_email, $subject, $description)
|
|
||||||
{
|
|
||||||
config([
|
|
||||||
'mail.mailers.smtp.transport' => get_settings('protocol'),
|
|
||||||
'mail.mailers.smtp.host' => get_settings('smtp_host'),
|
|
||||||
'mail.mailers.smtp.port' => get_settings('smtp_port'),
|
|
||||||
'mail.mailers.smtp.encryption' => get_settings('smtp_crypto'),
|
|
||||||
'mail.mailers.smtp.username' => get_settings('smtp_from_email'),
|
|
||||||
'mail.mailers.smtp.password' => get_settings('smtp_pass'),
|
|
||||||
'mail.from.address' => get_settings('smtp_from_email'),
|
|
||||||
'mail.from.name' => get_settings('smtp_user'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$mail_data['subject'] = $subject;
|
|
||||||
$mail_data['description'] = $description;
|
|
||||||
|
|
||||||
$send = Mail::to($user_email)->send(new Mailer($mail_data));
|
|
||||||
return $send;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,545 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Mail\Mailer;
|
|
||||||
use App\Models\Category;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use App\Models\Question;
|
|
||||||
use App\Models\QuizSubmission;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\Section;
|
|
||||||
use App\Models\SeoField;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class CourseController extends Controller
|
|
||||||
{
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
$category = 'all';
|
|
||||||
$status = 'all';
|
|
||||||
$instructor = 'all';
|
|
||||||
$price = 'all';
|
|
||||||
|
|
||||||
$query = Course::query();
|
|
||||||
$query1 = Course::query();
|
|
||||||
|
|
||||||
if (isset($request->category) && $request->category != '' && $request->category != 'all') {
|
|
||||||
|
|
||||||
$category_details = Category::where('slug', $request->category)->first();
|
|
||||||
if ($category_details->parent_id > 0) {
|
|
||||||
$page_data['child_cat'] = $request->category;
|
|
||||||
$query = $query->where('category_id', $category_details->id);
|
|
||||||
} else {
|
|
||||||
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id')->toArray();
|
|
||||||
$sub_cat_id[] = $category_details->id;
|
|
||||||
$query = $query->whereIn('category_id', $sub_cat_id);
|
|
||||||
$page_data['parent_cat'] = $request->category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search filter
|
|
||||||
if (isset($_GET['search']) && $_GET['search'] != '') {
|
|
||||||
$query = $query->where('title', 'LIKE', '%' . $_GET['search'] . '%');
|
|
||||||
}
|
|
||||||
|
|
||||||
// selected price
|
|
||||||
if (isset($_GET['price']) && $_GET['price'] != '' && $_GET['price'] != 'all') {
|
|
||||||
$search_price = 2;
|
|
||||||
if ($_GET['price'] == 'free') {
|
|
||||||
$search_price = 0;
|
|
||||||
} elseif ($_GET['price'] == 'paid') {
|
|
||||||
$search_price = 1;
|
|
||||||
}
|
|
||||||
$query = $query->where('is_paid', $search_price);
|
|
||||||
$price = $_GET['price'];
|
|
||||||
}
|
|
||||||
// selected instructor
|
|
||||||
if (isset($_GET['instructor']) && $_GET['instructor'] != '' && $_GET['instructor'] != 'all') {
|
|
||||||
$query = $query->where('user_id', $_GET['instructor']);
|
|
||||||
$instructor = $_GET['instructor'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// status filter
|
|
||||||
if (isset($_GET['status']) && $_GET['status'] != '' && $_GET['status'] != 'all') {
|
|
||||||
|
|
||||||
if ($_GET['status'] == 'active') {
|
|
||||||
$search_status = 'active';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'inactive') {
|
|
||||||
$search_status = 'inactive';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'pending') {
|
|
||||||
$search_status = 'pending';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'private') {
|
|
||||||
$search_status = 'private';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'upcoming') {
|
|
||||||
$search_status = 'upcoming';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'draft') {
|
|
||||||
$search_status = 'draft';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
}
|
|
||||||
$status = $_GET['status'];
|
|
||||||
}
|
|
||||||
$page_data['status'] = $status;
|
|
||||||
$page_data['instructor'] = $instructor;
|
|
||||||
$page_data['price'] = $price;
|
|
||||||
$page_data['courses'] = $query->orderBy('id', 'desc')->paginate(20)->appends(request()->query());
|
|
||||||
$page_data['pending_courses'] = Course::where('status', 'pending')->count();
|
|
||||||
$page_data['active_courses'] = Course::where('status', 'active')->count();
|
|
||||||
$page_data['upcoming_courses'] = Course::where('status', 'upcoming')->count();
|
|
||||||
$page_data['paid_courses'] = Course::where('is_paid', 1)->count();
|
|
||||||
$page_data['free_courses'] = Course::where('is_paid', 0)->count();
|
|
||||||
|
|
||||||
return view('admin.course.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
return view('admin.course.create');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'title' => 'required|max:255',
|
|
||||||
'category_id' => 'required|numeric|min:1',
|
|
||||||
'course_type' => 'required|in:general,scorm',
|
|
||||||
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
|
|
||||||
'level' => 'required|in:everyone,beginner,intermediate,advanced',
|
|
||||||
'language' => 'required',
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
'enable_drip_content' => Rule::in(['0', '1']),
|
|
||||||
'requirements' => 'array',
|
|
||||||
'outcomes' => 'array',
|
|
||||||
'faqs' => 'array',
|
|
||||||
'instructors' => 'required|array|min:1',
|
|
||||||
]);
|
|
||||||
//for normal form submission
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['course_type'] = $request->course_type;
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['level'] = $request->level;
|
|
||||||
$data['language'] = strtolower($request->language);
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
$data['enable_drip_content'] = $request->enable_drip_content;
|
|
||||||
|
|
||||||
|
|
||||||
$drip_content_settings = '{"lesson_completion_role":"percentage","minimum_duration":15,"minimum_percentage":"30","locked_lesson_message":"<h3 xss="removed" style="text-align: center; "><span xss="removed"><strong>Permission denied!<\/strong><\/span><\/h3><p xss="removed" style="text-align: center; "><span xss="removed">This course supports drip content, so you must complete the previous lessons.<\/span><\/p>"}';
|
|
||||||
|
|
||||||
$data['drip_content_settings'] = $drip_content_settings;
|
|
||||||
|
|
||||||
$meta_keywords = '';
|
|
||||||
$meta_keywords_arr = json_decode($request->meta_keywords, true);
|
|
||||||
if (is_array($meta_keywords_arr)) {
|
|
||||||
foreach ($meta_keywords_arr as $key => $keyword) {
|
|
||||||
if ($key > 0) {
|
|
||||||
$meta_keywords .= ',' . $keyword['value'];
|
|
||||||
} else {
|
|
||||||
$meta_keywords .= $keyword['value'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['meta_keywords'] = $meta_keywords;
|
|
||||||
$data['meta_description'] = $request->meta_description;
|
|
||||||
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
|
|
||||||
//Course expiry period
|
|
||||||
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
|
|
||||||
$data['expiry_period'] = $request->number_of_month;
|
|
||||||
} else {
|
|
||||||
$data['expiry_period'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove empty value by using array filter function
|
|
||||||
if (isset($request->requirements) && $request->requirements != '') {
|
|
||||||
|
|
||||||
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
}
|
|
||||||
if (isset($request->outcomes) && $request->outcomes != '') {
|
|
||||||
|
|
||||||
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($request->faq_title) && $request->faq_title != '') {
|
|
||||||
|
|
||||||
$faqs = [];
|
|
||||||
foreach ($request->faq_title as $key => $title) {
|
|
||||||
if ($title != '') {
|
|
||||||
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['faqs'] = json_encode($faqs);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['instructor_ids'] = json_encode($request->instructors);
|
|
||||||
$data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->banner) {
|
|
||||||
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
|
|
||||||
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->preview) {
|
|
||||||
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
|
|
||||||
FileUploader::upload($request->preview, $data['preview']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$course_id = Course::insertGetId($data);
|
|
||||||
Course::where('id', $course_id)->update(['slug' => slugify($request->title . '-' . $course_id)]);
|
|
||||||
|
|
||||||
//for normal form submission
|
|
||||||
return redirect(route('admin.course.edit', ['id' => $course_id]))->with('success', get_phrase('Course added successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit($course_id = "", Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
$data['course_details'] = Course::where('id', $course_id)->first();
|
|
||||||
$data['sections'] = Section::where('course_id', $course_id)->orderBy('sort')->get();
|
|
||||||
return view('admin.course.edit', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$query = Course::where('id', $id);
|
|
||||||
|
|
||||||
if ($request->tab == '') {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$rules = $data = [];
|
|
||||||
if ($request->tab == 'basic') {
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|max:255',
|
|
||||||
'category_id' => 'required|numeric|min:1',
|
|
||||||
'level' => 'required|in:everyone,beginner,intermediate,advanced',
|
|
||||||
'language' => 'required',
|
|
||||||
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
|
|
||||||
'instructors' => 'required|array|min:1',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title . '-' . $id);
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = removeScripts($request->description);
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['level'] = $request->level;
|
|
||||||
$data['language'] = strtolower($request->language);
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['instructor_ids'] = json_encode($request->instructors);
|
|
||||||
} elseif ($request->tab == 'pricing') {
|
|
||||||
$rules = [
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
|
|
||||||
//Course expiry period
|
|
||||||
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
|
|
||||||
$data['expiry_period'] = $request->number_of_month;
|
|
||||||
} else {
|
|
||||||
$data['expiry_period'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'info') {
|
|
||||||
$rules = [
|
|
||||||
'requirements' => 'array',
|
|
||||||
'outcomes' => 'array',
|
|
||||||
'faqs' => 'array',
|
|
||||||
];
|
|
||||||
|
|
||||||
//Remove empty value by using array filter function
|
|
||||||
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
|
|
||||||
$faqs = [];
|
|
||||||
foreach ($request->faq_title as $key => $title) {
|
|
||||||
if ($title != '') {
|
|
||||||
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['faqs'] = json_encode($faqs);
|
|
||||||
} elseif ($request->tab == 'media') {
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
remove_file($query->first()->thumbnail);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->banner) {
|
|
||||||
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
|
|
||||||
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
|
|
||||||
remove_file($query->first()->banner);
|
|
||||||
}
|
|
||||||
|
|
||||||
if($request->preview_video_provider == 'link'){
|
|
||||||
$data['preview'] = $request->preview_link;
|
|
||||||
}elseif($request->preview_video_provider == 'file' && $request->preview){
|
|
||||||
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
|
|
||||||
FileUploader::upload($request->preview, $data['preview']);
|
|
||||||
remove_file($query->first()->preview);
|
|
||||||
}
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'seo') {
|
|
||||||
$course_details = $query->first();
|
|
||||||
$SeoField = SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->first();
|
|
||||||
|
|
||||||
$seo_data['course_id'] = $id;
|
|
||||||
$seo_data['route'] = 'Course Details';
|
|
||||||
$seo_data['name_route'] = 'course.details';
|
|
||||||
$seo_data['meta_title'] = $request->meta_title;
|
|
||||||
$seo_data['meta_description'] = $request->meta_description;
|
|
||||||
$seo_data['meta_robot'] = $request->meta_robot;
|
|
||||||
$seo_data['canonical_url'] = $request->canonical_url;
|
|
||||||
$seo_data['custom_url'] = $request->custom_url;
|
|
||||||
$seo_data['json_ld'] = $request->json_ld;
|
|
||||||
$seo_data['og_title'] = $request->og_title;
|
|
||||||
$seo_data['og_description'] = $request->og_description;
|
|
||||||
$seo_data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$seo_data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
|
|
||||||
$meta_keywords_arr = json_decode($request->meta_keywords, true);
|
|
||||||
$meta_keywords = '';
|
|
||||||
if (is_array($meta_keywords_arr)) {
|
|
||||||
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
|
|
||||||
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
|
|
||||||
}
|
|
||||||
$seo_data['meta_keywords'] = $meta_keywords;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($request->og_image) {
|
|
||||||
$originalFileName = $course_details->id . '-' . $request->og_image->getClientOriginalName();
|
|
||||||
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
|
|
||||||
// Move the file to the destination path
|
|
||||||
FileUploader::upload($request->og_image, $destinationPath, 600);
|
|
||||||
$seo_data['og_image'] = $destinationPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($SeoField) {
|
|
||||||
if ($request->og_image) {
|
|
||||||
remove_file($SeoField->og_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->update($seo_data);
|
|
||||||
} else {
|
|
||||||
SeoField::insert($seo_data);
|
|
||||||
}
|
|
||||||
} elseif ($request->tab == 'drip-content') {
|
|
||||||
$rules = [
|
|
||||||
'enable_drip_content' => Rule::in(['0', '1']),
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['enable_drip_content'] = $request->enable_drip_content;
|
|
||||||
|
|
||||||
$lesson_completion_role = htmlspecialchars($request->input('lesson_completion_role'));
|
|
||||||
$minimum_duration_input = htmlspecialchars($request->input('minimum_duration'));
|
|
||||||
$minimum_percentage = htmlspecialchars($request->input('minimum_percentage'));
|
|
||||||
$locked_lesson_message = htmlspecialchars($request->input('locked_lesson_message'));
|
|
||||||
|
|
||||||
// Convert time (HH:MM:SS) to seconds
|
|
||||||
$time_parts = explode(':', $minimum_duration_input);
|
|
||||||
$seconds = ($time_parts[0] * 3600) + ($time_parts[1] * 60) + $time_parts[2];
|
|
||||||
|
|
||||||
$drip_data = [
|
|
||||||
'lesson_completion_role' => $lesson_completion_role,
|
|
||||||
'minimum_duration' => $seconds,
|
|
||||||
'minimum_percentage' => $minimum_percentage,
|
|
||||||
'locked_lesson_message' => $locked_lesson_message,
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['drip_content_settings'] = json_encode($drip_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->update($data);
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
return ['success' => get_phrase('Course updated successfully')];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function status($type, $id)
|
|
||||||
{
|
|
||||||
if ($type == 'active') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'active']);
|
|
||||||
} elseif ($type == 'pending') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'pending']);
|
|
||||||
} elseif ($type == 'inactive') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'inactive']);
|
|
||||||
} elseif ($type == 'upcoming') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'upcoming']);
|
|
||||||
} elseif ($type == 'private') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'private']);
|
|
||||||
} else {
|
|
||||||
Course::where('id', $id)->update(['status' => 'draft']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('admin.courses'))->with('success', get_phrase('Course status changed successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
// Find the course
|
|
||||||
$course = Course::find($id);
|
|
||||||
|
|
||||||
if (!$course) {
|
|
||||||
Session::flash('error', get_phrase('Course not found'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get all lessons associated with the course
|
|
||||||
$lessons = Lesson::where('course_id', $id)->get();
|
|
||||||
|
|
||||||
foreach ($lessons as $lesson) {
|
|
||||||
// Remove lesson files
|
|
||||||
remove_file($lesson->lesson_src);
|
|
||||||
remove_file('uploads/lesson_file/attachment/' . $lesson->attachment);
|
|
||||||
|
|
||||||
// If the lesson is a quiz, delete related questions and submissions
|
|
||||||
if ($lesson->lesson_type == 'quiz') {
|
|
||||||
Question::where('quiz_id', $lesson->id)->each(function ($question) {
|
|
||||||
$question->delete();
|
|
||||||
});
|
|
||||||
|
|
||||||
QuizSubmission::where('quiz_id', $lesson->id)->each(function ($submission) {
|
|
||||||
$submission->delete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the lesson
|
|
||||||
$lesson->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove course files
|
|
||||||
remove_file($course->thumbnail);
|
|
||||||
remove_file($course->banner);
|
|
||||||
remove_file($course->preview);
|
|
||||||
|
|
||||||
// Delete the course
|
|
||||||
$course->delete();
|
|
||||||
|
|
||||||
// Redirect with success message
|
|
||||||
return redirect(route('admin.courses'))->with('success', get_phrase('Course deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function draft($id)
|
|
||||||
{
|
|
||||||
$course = Course::where('id', $id)->first();
|
|
||||||
if (!$course) {
|
|
||||||
$response = [
|
|
||||||
'error' => get_phrase('Data not found.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = $course->status == 'active' ? 'deactivate' : 'active';
|
|
||||||
Course::where('id', $id)->update(['status' => $status]);
|
|
||||||
$response = [
|
|
||||||
'success' => get_phrase('Status has been updated.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function duplicate($id)
|
|
||||||
{
|
|
||||||
$course = Course::where('id', $id);
|
|
||||||
if (auth()->user()->role != 'admin') {
|
|
||||||
$course = $course->where('user_id', auth()->user()->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check course existence
|
|
||||||
if ($course->doesntExist()) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect course and remove unnecessary fields
|
|
||||||
$data = $course->first()->toArray();
|
|
||||||
if (auth()->user()->role == 'admin') {
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
}
|
|
||||||
unset($data['id'], $data['created_at'], $data['updated_at']);
|
|
||||||
|
|
||||||
// insert as new course
|
|
||||||
$course_id = Course::insertGetId($data);
|
|
||||||
Course::where('id', $course_id)->update(['slug' => slugify($data['title']).'-'.$course_id]);
|
|
||||||
|
|
||||||
// go to edit
|
|
||||||
Session::flash('success', get_phrase('Course duplicated.'));
|
|
||||||
return redirect()->route('admin.course.edit', $course_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function approval(Request $request, $id)
|
|
||||||
{
|
|
||||||
Course::where('id', $id)->update(['status' => 'active']);
|
|
||||||
|
|
||||||
$course = Course::where('id', $id)->first();
|
|
||||||
|
|
||||||
config([
|
|
||||||
'mail.mailers.smtp.transport' => get_settings('protocol'),
|
|
||||||
'mail.mailers.smtp.host' => get_settings('smtp_host'),
|
|
||||||
'mail.mailers.smtp.port' => get_settings('smtp_port'),
|
|
||||||
'mail.mailers.smtp.encryption' => get_settings('smtp_crypto'),
|
|
||||||
'mail.mailers.smtp.username' => get_settings('smtp_from_email'),
|
|
||||||
'mail.mailers.smtp.password' => get_settings('smtp_pass'),
|
|
||||||
'mail.from.address' => get_settings('smtp_from_email'),
|
|
||||||
'mail.from.name' => get_settings('smtp_user'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$mail_data['subject'] = $request->subject;
|
|
||||||
$mail_data['description'] = $request->message;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Mail::to($course->creator->email)->send(new Mailer($mail_data));
|
|
||||||
} catch (Exception $e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Course activated successfully'));
|
|
||||||
return redirect()->route('admin.courses');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,487 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use App\Models\Quiz;
|
|
||||||
use App\Models\Question;
|
|
||||||
use App\Models\QuizSubmission;
|
|
||||||
use App\Models\Section;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\File;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
|
|
||||||
class CurriculumController extends Controller
|
|
||||||
{
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$maximum_sort_value = Section::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
|
|
||||||
$request->validate([
|
|
||||||
'title' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$section = new Section();
|
|
||||||
$section->title = $request->title;
|
|
||||||
$section->user_id = auth()->user()->id;
|
|
||||||
$section->course_id = $request->course_id;
|
|
||||||
$section->sort = $maximum_sort_value + 1;
|
|
||||||
$done = $section->save();
|
|
||||||
Session::flash('success', get_phrase('Section added successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
Section::where('id', $request->section_id)->update(['title' => $request->up_title]);
|
|
||||||
Session::flash('success', get_phrase('update successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
|
|
||||||
Section::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function section_sort(Request $request)
|
|
||||||
{
|
|
||||||
$sections = json_decode($request->itemJSON);
|
|
||||||
foreach ($sections as $key => $value) {
|
|
||||||
$updater = $key + 1;
|
|
||||||
Section::where('id', $value)->update(['sort' => $updater]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Sections sorted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lesson_store(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
$maximum_sort_value = Lesson::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
$data['course_id'] = $request->course_id;
|
|
||||||
$data['section_id'] = $request->section_id;
|
|
||||||
$data['sort'] = $maximum_sort_value + 1;
|
|
||||||
$data['is_free'] = $request->free_lesson;
|
|
||||||
$data['lesson_type'] = $request->lesson_type;
|
|
||||||
$data['summary'] = $request->summary;
|
|
||||||
if ($request->lesson_type == 'text') {
|
|
||||||
$data['attachment'] = $request->text_description;
|
|
||||||
$data['attachment_type'] = $request->lesson_provider;
|
|
||||||
} elseif ($request->lesson_type == 'video-url') {
|
|
||||||
|
|
||||||
$data['video_type'] = $request->lesson_provider;
|
|
||||||
$data['lesson_src'] = $request->lesson_src;
|
|
||||||
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$data['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$data['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'html5') {
|
|
||||||
|
|
||||||
$data['video_type'] = $request->lesson_provider;
|
|
||||||
$data['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$data['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$data['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'document_type') {
|
|
||||||
|
|
||||||
if ($request->attachment == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$file = $file_name;
|
|
||||||
}
|
|
||||||
$data['attachment'] = $file;
|
|
||||||
$data['attachment_type'] = $request->attachment_type;
|
|
||||||
} elseif ($request->lesson_type == 'scorm') {
|
|
||||||
if ($request->scorm_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('scorm_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$upload_path = public_path('uploads/lesson_file/scorm_content');
|
|
||||||
|
|
||||||
if (! File::isDirectory($upload_path)) {
|
|
||||||
File::makeDirectory($upload_path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$item->move($upload_path, $file_name);
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
$zip_path = $upload_path . '/' . $file_name;
|
|
||||||
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
|
|
||||||
if ($zip->open($zip_path) === true) {
|
|
||||||
$zip->extractTo($extract_path);
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
File::delete($zip_path);
|
|
||||||
} else {
|
|
||||||
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['attachment'] = $file;
|
|
||||||
$data['attachment_type'] = $request->scorm_provider;
|
|
||||||
} elseif ($request->lesson_type == 'image') {
|
|
||||||
|
|
||||||
if ($request->attachment == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$file = $file_name;
|
|
||||||
}
|
|
||||||
$data['attachment'] = $file;
|
|
||||||
$data['attachment_type'] = $item->getClientOriginalExtension();
|
|
||||||
} elseif ($request->lesson_type == 'vimeo-url') {
|
|
||||||
|
|
||||||
$data['video_type'] = $request->lesson_provider;
|
|
||||||
$data['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$data['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$data['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'iframe') {
|
|
||||||
|
|
||||||
$data['lesson_src'] = $request->iframe_source;
|
|
||||||
} elseif ($request->lesson_type == 'google_drive') {
|
|
||||||
|
|
||||||
$data['video_type'] = $request->lesson_provider;
|
|
||||||
$data['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$data['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$data['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'system-video') {
|
|
||||||
|
|
||||||
if ($request->system_video_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('system_video_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/videos');
|
|
||||||
if (! File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = get_player_settings('watermark_type');
|
|
||||||
if ($type == 'ffmpeg') {
|
|
||||||
$watermark = get_player_settings('watermark_logo');
|
|
||||||
if (! $watermark) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! file_exists(public_path($watermark))) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$watermark_status = WatermarkController::encode($item, $file_name, $path);
|
|
||||||
if (! $watermark_status) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$file = FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['video_type'] = $request->lesson_provider;
|
|
||||||
$data['lesson_src'] = $file;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$data['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$data['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Lesson::insert($data);
|
|
||||||
Session::flash('success', get_phrase('lesson added successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lesson_sort(Request $request)
|
|
||||||
{
|
|
||||||
$lessons = json_decode($request->itemJSON);
|
|
||||||
foreach ($lessons as $key => $value) {
|
|
||||||
$updater = $key + 1;
|
|
||||||
Lesson::where('id', $value)->update(['sort' => $updater]);
|
|
||||||
}
|
|
||||||
Session::flash('success', get_phrase('Lessons sorted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lesson_edit(Request $request)
|
|
||||||
{
|
|
||||||
$current_data = Lesson::find($request->id);
|
|
||||||
|
|
||||||
$lesson['title'] = $request->title;
|
|
||||||
$lesson['section_id'] = $request->section_id;
|
|
||||||
$lesson['summary'] = $request->summary;
|
|
||||||
if ($request->lesson_type == 'text') {
|
|
||||||
$lesson['attachment'] = $request->text_description;
|
|
||||||
} elseif ($request->lesson_type == 'video-url') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'html5') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'document_type') {
|
|
||||||
if ($request->attachment) {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$lesson['attachment'] = $file_name;
|
|
||||||
$lesson['attachment_type'] = $request->attachment_type;
|
|
||||||
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'image') {
|
|
||||||
if ($request->attachment) {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$lesson['attachment'] = $file_name;
|
|
||||||
$lesson['attachment_type'] = $item->getClientOriginalExtension();
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'vimeo-url') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'iframe') {
|
|
||||||
$lesson['lesson_src'] = $request->iframe_source;
|
|
||||||
} elseif ($request->lesson_type == 'google_drive') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'scorm') {
|
|
||||||
|
|
||||||
$existing_scorm_folder = $request->attachment;
|
|
||||||
|
|
||||||
if ($request->scorm_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('scorm_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$upload_path = public_path('uploads/lesson_file/scorm_content');
|
|
||||||
|
|
||||||
if (! File::isDirectory($upload_path)) {
|
|
||||||
File::makeDirectory($upload_path, 0777, true, true);
|
|
||||||
}
|
|
||||||
$this->deleteDir(public_path('uploads/lesson_file/scorm_content/' . $existing_scorm_folder));
|
|
||||||
|
|
||||||
FileUploader::upload($request->scorm_file, 'uploads/lesson_file/scorm_content/' . $file_name);
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
$zip_path = $upload_path . '/' . $file_name;
|
|
||||||
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
|
|
||||||
// Remove old SCORM directory if it exists
|
|
||||||
$existing_scorm_path = $upload_path . '/' . $request->scorm_file;
|
|
||||||
if (File::isDirectory($existing_scorm_path)) {
|
|
||||||
File::deleteDirectory($existing_scorm_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($zip->open($zip_path) === true) {
|
|
||||||
$zip->extractTo($extract_path);
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
File::delete($zip_path);
|
|
||||||
} else {
|
|
||||||
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson['attachment'] = $file;
|
|
||||||
$lesson['attachment_type'] = $request->scorm_provider;
|
|
||||||
} elseif ($request->lesson_type == 'system-video') {
|
|
||||||
|
|
||||||
if ($request->system_video_file) {
|
|
||||||
$item = $request->file('system_video_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/videos');
|
|
||||||
if (! File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = get_player_settings('watermark_type');
|
|
||||||
if ($type == 'ffmpeg') {
|
|
||||||
$watermark = get_player_settings('watermark_logo');
|
|
||||||
if (! $watermark) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! file_exists(public_path($watermark))) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$watermark_status = WatermarkController::encode($item, $file_name, $path);
|
|
||||||
if (! $watermark_status) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
|
|
||||||
|
|
||||||
$file = str_replace(public_path('/'), '', $path).'/'. $file_name;
|
|
||||||
$lesson['lesson_src'] = $file;
|
|
||||||
remove_file($current_data->lesson_src);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Lesson::where('id', $request->id)->update($lesson);
|
|
||||||
Session::flash('success', get_phrase('lesson update successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteDir($directoryPath)
|
|
||||||
{
|
|
||||||
if (File::exists($directoryPath)) {
|
|
||||||
// Delete all files and subdirectories within the directory
|
|
||||||
File::deleteDirectory($directoryPath);
|
|
||||||
|
|
||||||
// Finally, delete the root directory itself
|
|
||||||
File::delete($directoryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function lesson_delete($id)
|
|
||||||
{
|
|
||||||
// Find the lesson
|
|
||||||
$current_data = Lesson::find($id);
|
|
||||||
|
|
||||||
if (!$current_data) {
|
|
||||||
Session::flash('error', get_phrase('Lesson not found'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove lesson files
|
|
||||||
remove_file($current_data->lesson_src);
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
|
|
||||||
// If the lesson is a quiz, delete related questions and submissions
|
|
||||||
if ($current_data->lesson_type == 'quiz') {
|
|
||||||
Question::where('quiz_id', $id)->each(function ($question) {
|
|
||||||
$question->delete();
|
|
||||||
});
|
|
||||||
|
|
||||||
QuizSubmission::where('quiz_id', $id)->each(function ($submission) {
|
|
||||||
$submission->delete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the lesson
|
|
||||||
$current_data->delete();
|
|
||||||
|
|
||||||
// Flash success message
|
|
||||||
Session::flash('success', get_phrase('Deleted successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,259 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Live_class;
|
|
||||||
use App\Models\Setting;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class LiveClassController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function live_class_start($id)
|
|
||||||
{
|
|
||||||
$live_class = Live_class::where('id', $id)->first();
|
|
||||||
|
|
||||||
if ($live_class->provider == 'zoom') {
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($live_class->additional_info, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_store(Request $request, $course_id)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'class_topic' => 'required|max:255',
|
|
||||||
'class_date_and_time' => 'date|required',
|
|
||||||
'user_id' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['class_topic'] = $request->class_topic;
|
|
||||||
$data['course_id'] = $request->course_id;
|
|
||||||
$data['user_id'] = $request->user_id;
|
|
||||||
$data['provider'] = $request->provider;
|
|
||||||
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$data['note'] = $request->note;
|
|
||||||
|
|
||||||
if ($request->provider == 'zoom') {
|
|
||||||
$meeting_info = $this->create_zoom_live_class($request->class_topic, $request->class_date_and_time);
|
|
||||||
$meeting_info_arr = json_decode($meeting_info, true);
|
|
||||||
if (array_key_exists('code', $meeting_info_arr) && $meeting_info_arr) {
|
|
||||||
return redirect(route('admin.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('error', get_phrase($meeting_info_arr['message']));
|
|
||||||
}
|
|
||||||
$data['additional_info'] = $meeting_info;
|
|
||||||
}
|
|
||||||
Live_class::insert($data);
|
|
||||||
|
|
||||||
return redirect(route('admin.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class added successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$previous_meeting_data = Live_class::where('id', $id)->first();
|
|
||||||
|
|
||||||
$request->validate([
|
|
||||||
'class_topic' => 'required|max:255',
|
|
||||||
'class_date_and_time' => 'date|required',
|
|
||||||
'user_id' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['class_topic'] = $request->class_topic;
|
|
||||||
$data['user_id'] = $request->user_id;
|
|
||||||
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$data['note'] = $request->note;
|
|
||||||
|
|
||||||
if ($previous_meeting_data->provider == 'zoom') {
|
|
||||||
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
|
|
||||||
$this->update_zoom_live_class($request->class_topic, $request->class_date_and_time, $previous_meeting_info['id']);
|
|
||||||
$previous_meeting_info["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$previous_meeting_info["topic"] = $request->class_topic;
|
|
||||||
$data['additional_info'] = json_encode($previous_meeting_info);
|
|
||||||
}
|
|
||||||
Live_class::where('id', $id)->update($data);
|
|
||||||
|
|
||||||
return redirect(route('admin.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class updated successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_delete($id)
|
|
||||||
{
|
|
||||||
$previous_meeting_data = Live_class::where('id', $id)->first();
|
|
||||||
$course = Course::where('id', $previous_meeting_data->course_id)->first();
|
|
||||||
|
|
||||||
if ($course->instructors()->count() > 0) {
|
|
||||||
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
|
|
||||||
$this->delete_zoom_live_class($previous_meeting_info['id']);
|
|
||||||
Live_class::where('id', $id)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('admin.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_settings()
|
|
||||||
{
|
|
||||||
return view('admin.setting.live_class_settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_live_class_settings(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'zoom_account_email' => 'required:email',
|
|
||||||
'zoom_web_sdk' => 'required|in:active,inactive',
|
|
||||||
'zoom_account_id' => 'required',
|
|
||||||
'zoom_client_id' => 'required',
|
|
||||||
'zoom_client_secret' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
foreach ($request->all() as $name => $value) {
|
|
||||||
if (Setting::where('type', $name)->count() > 0) {
|
|
||||||
Setting::where('type', $name)->update(['description' => $value]);
|
|
||||||
} else {
|
|
||||||
Setting::insert(['type' => $name, 'description' => $value]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('admin.live.class.settings'))->with('success', get_phrase('Zoom live class settings has been configured'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_live_class($topic, $date_and_time)
|
|
||||||
{
|
|
||||||
$zoom_account_email = get_settings('zoom_account_email');
|
|
||||||
$token = $this->create_zoom_token();
|
|
||||||
// API Endpoint for creating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
|
|
||||||
|
|
||||||
// Meeting data
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'schedule_for' => $zoom_account_email,
|
|
||||||
'type' => 2, // Scheduled meeting
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
|
|
||||||
'duration' => 60, // Duration in minutes
|
|
||||||
'timezone' => get_settings('timezone'), // Timezone
|
|
||||||
'settings' => [
|
|
||||||
'approval_type' => 2,
|
|
||||||
'join_before_host' => true,
|
|
||||||
'jbh_time' => 0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make POST request to create meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_zoom_live_class($topic, $date_and_time, $meetingId)
|
|
||||||
{
|
|
||||||
$token = $this->create_zoom_token(); // Obtain the access token
|
|
||||||
|
|
||||||
// API Endpoint for updating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Meeting data with updated start time
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // New start time (in UTC)
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make PATCH request to update meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete_zoom_live_class($meetingId)
|
|
||||||
{
|
|
||||||
$token = $this->create_zoom_token(); // Obtain the access token
|
|
||||||
|
|
||||||
// API Endpoint for deleting a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make DELETE request to delete meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_token()
|
|
||||||
{
|
|
||||||
// Access the environment variables
|
|
||||||
$clientId = get_settings('zoom_client_id');
|
|
||||||
$clientSecret = get_settings('zoom_client_secret');
|
|
||||||
$accountId = get_settings('zoom_account_id');
|
|
||||||
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
|
|
||||||
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
|
|
||||||
|
|
||||||
$curl = curl_init();
|
|
||||||
|
|
||||||
curl_setopt_array($curl, array(
|
|
||||||
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => '',
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
||||||
CURLOPT_HTTPHEADER => array(
|
|
||||||
'Content-Type: application/x-www-form-urlencoded',
|
|
||||||
'Authorization: ' . $authHeader,
|
|
||||||
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
|
|
||||||
$accessToken = $oauthResponse['access_token'];
|
|
||||||
return $accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class ModalController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function common_view_function(Request $request, $view_path = "")
|
|
||||||
{
|
|
||||||
$page_data = array();
|
|
||||||
foreach ($request->all() as $key => $value) :
|
|
||||||
$page_data[$key] = $value;
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,445 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use Anand\LaravelPaytmWallet\Facades\PaytmWallet;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\payment_gateway\Paystack;
|
|
||||||
use App\Models\payment_gateway\Ccavenue;
|
|
||||||
use App\Models\payment_gateway\Pagseguro;
|
|
||||||
use App\Models\payment_gateway\Xendit;
|
|
||||||
use App\Models\payment_gateway\Doku;
|
|
||||||
use App\Models\payment_gateway\Skrill;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use paytm\paytmchecksum\PaytmChecksum;
|
|
||||||
|
|
||||||
class PaymentController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
if (!$payment_details || !is_array($payment_details) || count($payment_details) <= 0) {
|
|
||||||
Session::flash('error', get_phrase('Payment not configured yet'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
if ($payment_details['payable_amount'] <= 0) {
|
|
||||||
Session::flash('error', get_phrase("Payable amount cannot be less than 1"));
|
|
||||||
return redirect()->to($payment_details['cancel_url']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['payment_details'] = $payment_details;
|
|
||||||
$page_data['payment_gateways'] = DB::table('payment_gateways')->where('status', 1)->get();
|
|
||||||
return view('payment.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show_payment_gateway_by_ajax($identifier)
|
|
||||||
{
|
|
||||||
$page_data['payment_details'] = session('payment_details');
|
|
||||||
$page_data['payment_gateway'] = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
return view('payment.' . $identifier . '.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function payment_success(Request $request, $identifier = "")
|
|
||||||
{
|
|
||||||
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$model_name = $payment_gateway->model_name;
|
|
||||||
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
|
|
||||||
|
|
||||||
$status = $model_full_path::payment_status($identifier, $request->all());
|
|
||||||
if ($status === true) {
|
|
||||||
$success_model = $payment_details['success_method']['model_name'];
|
|
||||||
$success_function = $payment_details['success_method']['function_name'];
|
|
||||||
|
|
||||||
$model_full_path = str_replace(' ', '', 'App\Models\ ' . $success_model);
|
|
||||||
return $model_full_path::$success_function($identifier);
|
|
||||||
} elseif ($status == "submitted") {
|
|
||||||
Session::flash('success', get_phrase('Your payment submitted. It will take some times to enrol.'));
|
|
||||||
return redirect(route('home'));
|
|
||||||
} else {
|
|
||||||
Session::flash('error', get_phrase('Payment failed! Please try again.'));
|
|
||||||
redirect()->to($payment_details['cancel_url']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function payment_create($identifier)
|
|
||||||
{
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$model_name = $payment_gateway->model_name;
|
|
||||||
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
|
|
||||||
$created_payment_link = $model_full_path::payment_create($identifier);
|
|
||||||
|
|
||||||
return redirect()->to($created_payment_link);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function payment_notification(Request $request, $identifier)
|
|
||||||
{
|
|
||||||
if ($identifier == 'doku') {
|
|
||||||
Doku::payment_status($identifier, $request->all(), $request->headers->all());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function payment_razorpay($identifier)
|
|
||||||
{
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$model_name = $payment_gateway->model_name;
|
|
||||||
$model_full_path = str_replace(' ', '', 'App\Models\payment_gateway\ ' . $model_name);
|
|
||||||
$data = $model_full_path::payment_create($identifier);
|
|
||||||
|
|
||||||
return view('payment.razorpay.payment', compact('data'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function make_paytm_order(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
//start common code of all payment gateway
|
|
||||||
// $identifier = 'paytm';
|
|
||||||
// $payment_details = session('payment_details');
|
|
||||||
// $model = $payment_details['success_method']['model_name'];
|
|
||||||
// $payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
// $user = auth()->user();
|
|
||||||
|
|
||||||
// $paytm_merchant_key = $paytm_merchant_mid = $paytm_merchant_website = $industry_type_id = $channel_id = '';
|
|
||||||
// if ($model == 'InstructorPayment') {
|
|
||||||
// $instructor_payment_keys = DB::table('users')
|
|
||||||
// ->where('id', $payment_details['items'][0]['id'])
|
|
||||||
// ->value('paymentkeys');
|
|
||||||
// $keys = isset($instructor_payment_keys) ? json_decode($instructor_payment_keys) : null;
|
|
||||||
// if ($keys) {
|
|
||||||
// $paytm_merchant_key = $keys->paytm->paytm_merchant_key;
|
|
||||||
// $paytm_merchant_mid = $keys->paytm->paytm_merchant_mid;
|
|
||||||
// $paytm_merchant_website = $keys->paytm->paytm_merchant_website;
|
|
||||||
// $industry_type_id = $keys->paytm->industry_type_id;
|
|
||||||
// $channel_id = $keys->paytm->channel_id;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// $keys = json_decode($payment_gateway->keys);
|
|
||||||
// $paytm_merchant_key = $keys->paytm_merchant_key;
|
|
||||||
// $paytm_merchant_mid = $keys->paytm_merchant_mid;
|
|
||||||
// $paytm_merchant_website = $keys->paytm_merchant_website;
|
|
||||||
// $industry_type_id = $keys->industry_type_id;
|
|
||||||
// $channel_id = $keys->channel_id;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if ($payment_gateway->test_mode == 1) {
|
|
||||||
// $PAYTM_STATUS_QUERY_NEW_URL = 'https://securegw-stage.paytm.in/merchant-status/getTxnStatus';
|
|
||||||
// $PAYTM_TXN_URL = 'https://securegw-stage.paytm.in/theia/processTransaction';
|
|
||||||
// } else {
|
|
||||||
// define('PAYTM_ENVIRONMENT', 'PROD'); // PROD or TEST
|
|
||||||
// $PAYTM_STATUS_QUERY_NEW_URL = 'https://securegw.paytm.in/merchant-status/getTxnStatus';
|
|
||||||
// $PAYTM_TXN_URL = 'https://securegw.paytm.in/theia/processTransaction';
|
|
||||||
// }
|
|
||||||
// $paramList = [];
|
|
||||||
// $paramList['MID'] = $paytm_merchant_mid;
|
|
||||||
// $paramList['ORDER_ID'] = 'ORDS2123' . $user->id;
|
|
||||||
// $paramList['CUST_ID'] = 'CUST' . $user->id;
|
|
||||||
// $paramList['INDUSTRY_TYPE_ID'] = $industry_type_id;
|
|
||||||
// $paramList['CHANNEL_ID'] = $channel_id;
|
|
||||||
// $paramList['TXN_AMOUNT'] = $payment_details['payable_amount'];
|
|
||||||
// $paramList['WEBSITE'] = $paytm_merchant_website;
|
|
||||||
// $paramList['CALLBACK_URL'] = $payment_details['success_url'] . '/' . $identifier;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// $paytmParams = array();
|
|
||||||
|
|
||||||
// $paytmParams["body"] = array(
|
|
||||||
// "requestType" => "Payment",
|
|
||||||
// "mid" => $paytm_merchant_mid,
|
|
||||||
// "websiteName" => $paytm_merchant_website,
|
|
||||||
// "orderId" => 'ORDS2123' . $user->id,
|
|
||||||
// "callbackUrl" => $payment_details['success_url'] . '/' . $identifier,
|
|
||||||
// "txnAmount" => array(
|
|
||||||
// "value" => round($payment_details['payable_amount'], 2),
|
|
||||||
// "currency" => "INR",
|
|
||||||
// ),
|
|
||||||
// "userInfo" => array(
|
|
||||||
// "custId" => "CUST_".$user->id,
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
// $checksum = PaytmChecksum::generateSignature(json_encode($paramList, JSON_UNESCAPED_SLASHES), $paytm_merchant_key);
|
|
||||||
// echo PaytmChecksum::verifySignature($paramList, $paytm_merchant_key, $checksum);
|
|
||||||
|
|
||||||
// // $checksum = str_replace('/', '', $checksum);
|
|
||||||
// // $checksum = str_replace('=', '', $checksum);
|
|
||||||
|
|
||||||
// $paytmParams["head"] = array(
|
|
||||||
// "signature" => $checksum,
|
|
||||||
// "channelId" => $channel_id
|
|
||||||
// );
|
|
||||||
|
|
||||||
// $post_data = json_encode($paytmParams, JSON_UNESCAPED_SLASHES);
|
|
||||||
|
|
||||||
// /* for Staging */
|
|
||||||
// $url = "https://securegw-stage.paytm.in/theia/api/v1/initiateTransaction?mid=$paytm_merchant_mid&orderId=ORDS2123" . $user->id;
|
|
||||||
|
|
||||||
// $ch = curl_init($url);
|
|
||||||
// curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
// curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
|
|
||||||
// curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
// curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/json"));
|
|
||||||
// $response = curl_exec($ch);
|
|
||||||
// print_r($response);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return view('payment.paytm.paytm_merchant_checkout');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function paytm_paymentCallback()
|
|
||||||
{
|
|
||||||
$transaction = PaytmWallet::with('receive');
|
|
||||||
$response = $transaction->response();
|
|
||||||
$order_id = $transaction->getOrderId(); // return a order id
|
|
||||||
$transaction->getTransactionId(); // return a transaction id
|
|
||||||
|
|
||||||
// update the db data as per result from api call
|
|
||||||
if ($transaction->isSuccessful()) {
|
|
||||||
Paytm::where('order_id', $order_id)->update(['status' => 1, 'transaction_id' => $transaction->getTransactionId()]);
|
|
||||||
return redirect(route('initiate.payment'))->with('message', "Your payment is successfull.");
|
|
||||||
} else if ($transaction->isFailed()) {
|
|
||||||
Paytm::where('order_id', $order_id)->update(['status' => 0, 'transaction_id' => $transaction->getTransactionId()]);
|
|
||||||
return redirect(route('initiate.payment'))->with('message', "Your payment is failed.");
|
|
||||||
} else if ($transaction->isOpen()) {
|
|
||||||
Paytm::where('order_id', $order_id)->update(['status' => 2, 'transaction_id' => $transaction->getTransactionId()]);
|
|
||||||
return redirect(route('initiate.payment'))->with('message', "Your payment is processing.");
|
|
||||||
}
|
|
||||||
$transaction->getResponseMessage(); //Get Response Message If Available
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function doku_checkout($identifier)
|
|
||||||
{
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
$test_mode = $payment_gateway->test_mode == 1 ? 1 : 0;
|
|
||||||
$client_id = $keys['client_id'];
|
|
||||||
if ($test_mode == 1) {
|
|
||||||
$key = $keys['public_test_key'];
|
|
||||||
$secret_key = $keys['secret_test_key'];
|
|
||||||
} else {
|
|
||||||
$key = $keys['public_live_key'];
|
|
||||||
$secret_key = $keys['secret_live_key'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$user_id = auth()->user()->id;
|
|
||||||
$user = DB::table('users')->where('id', $user_id)->first();
|
|
||||||
$currency = $payment_gateway->currency;
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$product_title = $payment_details['items'][0]['title'];
|
|
||||||
$amount = $payment_details['items'][0]['price'];
|
|
||||||
|
|
||||||
//Store temporary data
|
|
||||||
Doku::storeTempData();
|
|
||||||
|
|
||||||
$requestBody = array(
|
|
||||||
'order' => array(
|
|
||||||
'amount' => $amount,
|
|
||||||
'invoice_number' => 'INV-' . rand(1, 10000), // Change to your business logic
|
|
||||||
'currency' => $currency,
|
|
||||||
'callback_url' => $payment_details["success_url"] . "/$identifier",
|
|
||||||
'line_items' => array(
|
|
||||||
0 => array(
|
|
||||||
'name' => $product_title,
|
|
||||||
'price' => $amount,
|
|
||||||
'quantity' => 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
'payment' => array(
|
|
||||||
'payment_due_date' => 60,
|
|
||||||
),
|
|
||||||
'customer' => array(
|
|
||||||
'id' => 'CUST-' . rand(1, 1000), // Change to your customer ID mapping
|
|
||||||
'name' => $user->name,
|
|
||||||
'email' => $user->email,
|
|
||||||
'phone' => $user->phone,
|
|
||||||
'address' => $user->address,
|
|
||||||
'country' => 'ID',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
$requestId = rand(1, 100000); // Change to UUID or anything that can generate unique value
|
|
||||||
$dateTime = gmdate("Y-m-d H:i:s");
|
|
||||||
$isoDateTime = date(DATE_ISO8601, strtotime($dateTime));
|
|
||||||
$dateTimeFinal = substr($isoDateTime, 0, 19) . "Z";
|
|
||||||
$clientId = $client_id; // Change with your Client ID
|
|
||||||
$secretKey = $secret_key; // Change with your Secret Key
|
|
||||||
|
|
||||||
// $getUrl = 'https://api-sandbox.doku.com';
|
|
||||||
|
|
||||||
if ($test_mode == 1) {
|
|
||||||
$getUrl = 'https://api-sandbox.doku.com';
|
|
||||||
} else {
|
|
||||||
$getUrl = 'https://api.doku.com';
|
|
||||||
}
|
|
||||||
|
|
||||||
$targetPath = '/checkout/v1/payment';
|
|
||||||
$url = $getUrl . $targetPath;
|
|
||||||
|
|
||||||
// Generate digest
|
|
||||||
$digestValue = base64_encode(hash('sha256', json_encode($requestBody), true));
|
|
||||||
|
|
||||||
// Prepare signature component
|
|
||||||
$componentSignature = "Client-Id:" . $clientId . "\n" .
|
|
||||||
"Request-Id:" . $requestId . "\n" .
|
|
||||||
"Request-Timestamp:" . $dateTimeFinal . "\n" .
|
|
||||||
"Request-Target:" . $targetPath . "\n" .
|
|
||||||
"Digest:" . $digestValue;
|
|
||||||
|
|
||||||
// Generate signature
|
|
||||||
$signature = base64_encode(hash_hmac('sha256', $componentSignature, $secretKey, true));
|
|
||||||
|
|
||||||
// Execute request
|
|
||||||
$ch = curl_init($url);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($requestBody));
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
|
|
||||||
'Content-Type: application/json',
|
|
||||||
'Client-Id:' . $clientId,
|
|
||||||
'Request-Id:' . $requestId,
|
|
||||||
'Request-Timestamp:' . $dateTimeFinal,
|
|
||||||
'Signature:' . "HMACSHA256=" . $signature,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Set response json
|
|
||||||
$responseJson = curl_exec($ch);
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
// Echo the response
|
|
||||||
if (is_string($responseJson) && $httpCode == 200) {
|
|
||||||
return json_decode($responseJson, true);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function webRedirectToPayFee(Request $request)
|
|
||||||
{
|
|
||||||
// Check if the 'auth' query parameter is present
|
|
||||||
if (!$request->has('auth')) {
|
|
||||||
return redirect()->route('login')->withErrors([
|
|
||||||
'email' => 'Authentication token is missing.',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the 'Basic ' prefix
|
|
||||||
// $base64Credentials = $request->query('auth');
|
|
||||||
// Remove the 'Basic ' prefix
|
|
||||||
$base64Credentials = substr($request->query('auth'), 6);
|
|
||||||
|
|
||||||
// Decode the base64-encoded string
|
|
||||||
$credentials = base64_decode($base64Credentials);
|
|
||||||
|
|
||||||
// Split the decoded string into email, password, and timestamp
|
|
||||||
list($email, $password, $timestamp) = explode(':', $credentials);
|
|
||||||
|
|
||||||
// Get the current timestamp
|
|
||||||
$timestamp1 = strtotime(date('Y-m-d'));
|
|
||||||
|
|
||||||
// Calculate the difference
|
|
||||||
$difference = $timestamp1 - $timestamp;
|
|
||||||
|
|
||||||
if ($difference < 86400) {
|
|
||||||
if (auth()->attempt(['email' => $email, 'password' => $password])) {
|
|
||||||
// Authentication passed...
|
|
||||||
return redirect(route('cart'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->route('login')->withErrors([
|
|
||||||
'email' => 'Invalid email or password',
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
return redirect()->route('login')->withErrors([
|
|
||||||
'email' => 'Token expired!',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Models\Certificate;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Enrollment;
|
|
||||||
use App\Models\Forum;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use App\Models\Watch_history;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class PlayerController extends Controller
|
|
||||||
{
|
|
||||||
public function course_player(Request $request, $slug, $id = '')
|
|
||||||
{
|
|
||||||
$course = Course::where('slug', $slug)->firstOrNew();
|
|
||||||
|
|
||||||
// check if course is paid
|
|
||||||
if ($course->is_paid && auth()->user()->role != 'admin') {
|
|
||||||
if (auth()->user()->role == 'student') { // for student check enrollment status
|
|
||||||
$enroll_status = enroll_status($course->id, auth()->user()->id);
|
|
||||||
if ($enroll_status == 'expired') {
|
|
||||||
Session::flash('error', get_phrase('Your course accessibility has expired. You need to buy it again'));
|
|
||||||
return redirect()->route('course.details', ['slug' => $slug]);
|
|
||||||
} elseif(! $enroll_status) {
|
|
||||||
Session::flash('error', get_phrase('Not registered for this course.'));
|
|
||||||
return redirect()->route('course.details', ['slug' => $slug]);
|
|
||||||
}
|
|
||||||
} elseif (auth()->user()->role == 'instructor') { // for instructor check who is course instructor
|
|
||||||
if ($course->user_id != auth()->user()->id) {
|
|
||||||
Session::flash('error', get_phrase('Not valid instructor.'));
|
|
||||||
return redirect()->route('my.courses');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$check_lesson_history = Watch_history::where('course_id', $course->id)
|
|
||||||
->where('student_id', auth()->user()->id)->first();
|
|
||||||
$first_lesson_of_course = Lesson::where('course_id', $course->id)->orderBy('sort', 'asc')->value('id');
|
|
||||||
if ($id == '') {
|
|
||||||
$id = $check_lesson_history->watching_lesson_id ?? $first_lesson_of_course;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if user has any watched history or not
|
|
||||||
if (! $check_lesson_history && $id > 0) {
|
|
||||||
$data = [
|
|
||||||
'course_id' => $course->id,
|
|
||||||
'student_id' => auth()->user()->id,
|
|
||||||
'watching_lesson_id' => $id,
|
|
||||||
'completed_lesson' => json_encode([])
|
|
||||||
];
|
|
||||||
Watch_history::insert($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// when user plays a lesson, update that lesson id as watch history
|
|
||||||
if ($id > 0) {
|
|
||||||
Watch_history::where('course_id', $course->id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->update(['watching_lesson_id' => $id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['course_details'] = $course;
|
|
||||||
$page_data['lesson_details'] = Lesson::where('id', $id)->firstOrNew();
|
|
||||||
$page_data['history'] = Watch_history::where('course_id', $course->id)->where('student_id', auth()->user()->id)->first();
|
|
||||||
|
|
||||||
$forum_query = Forum::join('users', 'forums.user_id', 'users.id')
|
|
||||||
->select('forums.*', 'users.name as user_name', 'users.photo as user_photo')
|
|
||||||
->latest('forums.id')
|
|
||||||
->where('forums.parent_id', 0)
|
|
||||||
->where('forums.course_id', $course->id);
|
|
||||||
|
|
||||||
if (isset($_GET['search'])) {
|
|
||||||
$forum_query->where(function ($query) use ($request) {
|
|
||||||
$query->where('forums.title', 'like', '%' . $request->search . '%')->where('forums.description', 'like', '%' . $request->search . '%');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['questions'] = $forum_query->get();
|
|
||||||
|
|
||||||
return view('course_player.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set_watch_history(Request $request)
|
|
||||||
{
|
|
||||||
$course = Course::where('id', $request->course_id)->first();
|
|
||||||
$enrollment = Enrollment::where('course_id', $course->id)->where('user_id', auth()->user()->id)->first();
|
|
||||||
if (! $enrollment && (auth()->user()->role != 'admin' || ! is_course_instructor($course->id))) {
|
|
||||||
Session::flash('error', get_phrase('Not registered for this course.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['course_id'] = $request->course_id;
|
|
||||||
$data['student_id'] = auth()->user()->id;
|
|
||||||
|
|
||||||
$total_lesson = Lesson::where('course_id', $request->course_id)->pluck('id')->toArray();
|
|
||||||
|
|
||||||
$watch_history = Watch_history::where('course_id', $request->course_id)
|
|
||||||
->where('student_id', auth()->user()->id)->first();
|
|
||||||
|
|
||||||
if (isset($watch_history) && $watch_history->id) {
|
|
||||||
$lessons = (array) json_decode($watch_history->completed_lesson);
|
|
||||||
if (! in_array($request->lesson_id, $lessons)) {
|
|
||||||
array_push($lessons, $request->lesson_id);
|
|
||||||
} else {
|
|
||||||
while (($key = array_search($request->lesson_id, $lessons)) !== false) {
|
|
||||||
unset($lessons[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['completed_lesson'] = json_encode($lessons);
|
|
||||||
$data['watching_lesson_id'] = $request->lesson_id;
|
|
||||||
$data['completed_date'] = (count($total_lesson) == count($lessons)) ? time() : null;
|
|
||||||
Watch_history::where('course_id', $request->course_id)->where('student_id', auth()->user()->id)->update($data);
|
|
||||||
} else {
|
|
||||||
$lessons = [$request->lesson_id];
|
|
||||||
$data['completed_lesson'] = json_encode($lessons);
|
|
||||||
$data['watching_lesson_id'] = $request->lesson_id;
|
|
||||||
$data['completed_date'] = (count($total_lesson) == count($lessons)) ? time() : null;
|
|
||||||
Watch_history::insert($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress_bar($request->course_id) >= 100) {
|
|
||||||
$certificate = Certificate::where('user_id', auth()->user()->id)->where('course_id', $request->course_id);
|
|
||||||
|
|
||||||
if ($certificate->count() == 0) {
|
|
||||||
$certificate_data['user_id'] = auth()->user()->id;
|
|
||||||
$certificate_data['course_id'] = $request->course_id;
|
|
||||||
$certificate_data['identifier'] = random(12);
|
|
||||||
$certificate_data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
Certificate::insert($certificate_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function prepend_watermark()
|
|
||||||
{
|
|
||||||
return view('course_player.watermark');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,692 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Models\Application;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Enrollment;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\Payout;
|
|
||||||
use App\Models\Permission;
|
|
||||||
use App\Models\Setting;
|
|
||||||
use App\Models\Message;
|
|
||||||
use App\Models\MessageThread;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Response;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class UsersController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function admin_index(Request $request)
|
|
||||||
{
|
|
||||||
$query = User::where('role', 'admin');
|
|
||||||
if (isset($_GET['search']) && $_GET['search'] != '') {
|
|
||||||
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
|
|
||||||
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
|
|
||||||
}
|
|
||||||
$page_data['admins'] = $query->paginate(10);
|
|
||||||
return view('admin.admin.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function admin_create()
|
|
||||||
{
|
|
||||||
return view('admin.admin.create_admin');
|
|
||||||
}
|
|
||||||
public function admin_store(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => "required",
|
|
||||||
'email' => 'required|email|unique:users',
|
|
||||||
'password' => "required|min:8",
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['password'] = Hash::make($request->password);
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['role'] = 'admin';
|
|
||||||
$data['status'] = '1';
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
$done = User::insert($data);
|
|
||||||
|
|
||||||
if ($done) {
|
|
||||||
$admin_id = User::latest('id')->first();
|
|
||||||
Permission::insert(['admin_id' => $admin_id->id]);
|
|
||||||
}
|
|
||||||
Session::flash('success', get_phrase('Admin add successfully'));
|
|
||||||
return redirect()->route('admin.admins.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function admin_edit($id)
|
|
||||||
{
|
|
||||||
$page_data['admin'] = User::where('id', $id)->first();
|
|
||||||
return view('admin.admin.edit_admin', $page_data);
|
|
||||||
}
|
|
||||||
public function admin_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required|max:255',
|
|
||||||
'email' => "required|email|unique:users,email,$id",
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
remove_file(User::where('id', $id)->first()->photo);
|
|
||||||
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
User::where('id', $request->id)->update($data);
|
|
||||||
Session::flash('success', get_phrase('Admin update successfully'));
|
|
||||||
return redirect()->route('admin.admins.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function admin_delete($id)
|
|
||||||
{
|
|
||||||
$threads = MessageThread::where('contact_one', $id)
|
|
||||||
->orWhere('contact_two', $id)
|
|
||||||
->pluck('id');
|
|
||||||
|
|
||||||
if ($threads->isNotEmpty()) {
|
|
||||||
Message::whereIn('thread_id', $threads)->delete();
|
|
||||||
MessageThread::whereIn('id', $threads)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
$done = User::where('id', $id)->delete();
|
|
||||||
if ($done) {
|
|
||||||
Permission::where('admin_id', $id)->delete();
|
|
||||||
}
|
|
||||||
Session::flash('success', get_phrase('Admin delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function admin_permission($user_id)
|
|
||||||
{
|
|
||||||
$page_data['admin'] = User::where('id', $user_id)->firstOrNew();
|
|
||||||
return view('admin.admin.permission', $page_data);
|
|
||||||
}
|
|
||||||
public function admin_permission_store(Request $request)
|
|
||||||
{
|
|
||||||
$user_id = $request->user_id;
|
|
||||||
|
|
||||||
$permission = Permission::where('admin_id', $user_id)->first();
|
|
||||||
|
|
||||||
if ($permission) {
|
|
||||||
$set_permission = json_decode($permission->permissions, true) ?? [];
|
|
||||||
if (in_array($request->permission, $set_permission)) {
|
|
||||||
$pos = array_search($request->permission, $set_permission);
|
|
||||||
array_splice($set_permission, $pos, 1);
|
|
||||||
} else {
|
|
||||||
array_push($set_permission, $request->permission);
|
|
||||||
}
|
|
||||||
Permission::where('admin_id', $user_id)->update(['permissions' => $set_permission]);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
$set_per = json_encode([$request->permission]);
|
|
||||||
Permission::insert(['admin_id' => $user_id, 'permissions' => $set_per]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_index()
|
|
||||||
{
|
|
||||||
$query = User::where('role', 'instructor');
|
|
||||||
if (isset($_GET['search']) && $_GET['search'] != '') {
|
|
||||||
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
|
|
||||||
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
|
|
||||||
}
|
|
||||||
$page_data['instructors'] = $query->paginate(10);
|
|
||||||
return view('admin.instructor.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_create()
|
|
||||||
{
|
|
||||||
return view('admin.instructor.create_instructor');
|
|
||||||
}
|
|
||||||
public function instructor_edit($id = '')
|
|
||||||
{
|
|
||||||
$page_data['instructor'] = User::where('id', $id)->first();
|
|
||||||
return view('admin.instructor.edit_instructor', $page_data);
|
|
||||||
}
|
|
||||||
public function instructor_store(Request $request, $id = '')
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => "required|max:255",
|
|
||||||
'email' => 'required|email|unique:users',
|
|
||||||
'password' => "required|min:8",
|
|
||||||
]);
|
|
||||||
|
|
||||||
if(get_settings('student_email_verification') != 1){
|
|
||||||
$data['email_verified_at'] = date('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['paymentkeys'] = json_encode($request->paymentkeys);
|
|
||||||
$data['status'] = '1';
|
|
||||||
|
|
||||||
$data['password'] = Hash::make($request->password);
|
|
||||||
$data['role'] = 'instructor';
|
|
||||||
|
|
||||||
$data['email_verified_at'] = $request->email_verified == 1 ? now() : null;
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
$user = User::create($data);
|
|
||||||
|
|
||||||
if(get_settings('student_email_verification') == 1) {
|
|
||||||
$user->sendEmailVerificationNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Instructor add successfully'));
|
|
||||||
|
|
||||||
return redirect()->route('admin.instructor.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_update(Request $request, $id = '')
|
|
||||||
{
|
|
||||||
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required|max:255',
|
|
||||||
'email' => "required|email|unique:users,email,$id",
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['paymentkeys'] = json_encode($request->paymentkeys);
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
remove_file(User::where('id', $id)->first()->photo);
|
|
||||||
$path = "uploads/users/instructor/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
User::where('id', $id)->update($data);
|
|
||||||
Session::flash('success', get_phrase('Instructor update successfully'));
|
|
||||||
return redirect()->route('admin.instructor.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_delete($id)
|
|
||||||
{
|
|
||||||
$threads = MessageThread::where('contact_one', $id)
|
|
||||||
->orWhere('contact_two', $id)
|
|
||||||
->pluck('id');
|
|
||||||
|
|
||||||
if ($threads->isNotEmpty()) {
|
|
||||||
Message::whereIn('thread_id', $threads)->delete();
|
|
||||||
MessageThread::whereIn('id', $threads)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
User::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Instructor delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_view_course(Request $request)
|
|
||||||
{
|
|
||||||
$course = Course::where('user_id', $request->id)->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_payout(Request $request)
|
|
||||||
{
|
|
||||||
$start_date = strtotime('first day of this month');
|
|
||||||
$end_date = strtotime('last day of this month');
|
|
||||||
$page_data['start_date'] = $start_date;
|
|
||||||
$page_data['end_date'] = $end_date;
|
|
||||||
$page_data['instructor_payout_complete'] = Payout::where('status', 1)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
|
|
||||||
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
|
|
||||||
$page_data['instructor_payout_incomplete'] = Payout::where('status', 0)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
|
|
||||||
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
|
|
||||||
return view('admin.instructor.payout', $page_data);
|
|
||||||
}
|
|
||||||
public function instructor_payout_filter(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
$date = explode('-', $request->eDateRange);
|
|
||||||
$start_date = strtotime($date[0] . ' 00:00:00');
|
|
||||||
$end_date = strtotime($date[1] . ' 23:59:59');
|
|
||||||
$page_data['start_date'] = $start_date;
|
|
||||||
$page_data['end_date'] = $end_date;
|
|
||||||
|
|
||||||
$page_data['instructor_payout_complete'] = Payout::where('status', 1)->where('created_at', '>=', date('Y-m-d H:i:s', $start_date))
|
|
||||||
->where('created_at', '<=', date('Y-m-d H:i:s', $end_date))->paginate(10);
|
|
||||||
$page_data['instructor_payout_incomplete'] = Payout::where('status', 0)->paginate(10);
|
|
||||||
|
|
||||||
return view('admin.instructor.payout', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_payout_invoice($id = '')
|
|
||||||
{
|
|
||||||
if ($id != '') {
|
|
||||||
$page_data['invoice_info'] = Payout::where('status', 1)->first();
|
|
||||||
$page_data['invoice_data'] = Payout::where('status', 1)->get();
|
|
||||||
$page_data['invoice_id'] = $id;
|
|
||||||
|
|
||||||
return view('admin.instructor.instructor_invoice', $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_payment(Request $request)
|
|
||||||
{
|
|
||||||
$id = $request->user_id;
|
|
||||||
$payable_amount = $request->amount;
|
|
||||||
$start_timestamp = time();
|
|
||||||
$end_timestamp = time();
|
|
||||||
|
|
||||||
$payment_details = [
|
|
||||||
'items' => [
|
|
||||||
[
|
|
||||||
'id' => $id,
|
|
||||||
'title' => get_phrase('Pay for instructor payout'),
|
|
||||||
'subtitle' => get_phrase(''),
|
|
||||||
'price' => $payable_amount,
|
|
||||||
'discount_price' => $payable_amount,
|
|
||||||
'discount_percentage' => 0,
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'custom_field' => [
|
|
||||||
'start_date' => date('Y-m-d H:i:s', $start_timestamp),
|
|
||||||
'end_date' => date('Y-m-d H:i:s', $end_timestamp),
|
|
||||||
'user_id' => auth()->user()->id,
|
|
||||||
'payout_id' => $request->payout_id,
|
|
||||||
|
|
||||||
],
|
|
||||||
'success_method' => [
|
|
||||||
'model_name' => 'InstructorPayment',
|
|
||||||
'function_name' => 'instructor_payment',
|
|
||||||
],
|
|
||||||
'tax' => 0,
|
|
||||||
'coupon' => null,
|
|
||||||
'payable_amount' => $payable_amount,
|
|
||||||
'cancel_url' => route('admin.instructor.payout'),
|
|
||||||
'success_url' => route('payment.success'),
|
|
||||||
];
|
|
||||||
session(['payment_details' => $payment_details]);
|
|
||||||
return redirect()->route('payment');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_setting()
|
|
||||||
{
|
|
||||||
$page_data['allow_instructor'] = Setting::where('type', 'allow_instructor')->first();
|
|
||||||
$page_data['application_note'] = Setting::where('type', 'instructor_application_note')->first();
|
|
||||||
$page_data['instructor_revenue'] = Setting::where('type', 'instructor_revenue')->first();
|
|
||||||
return view('admin.instructor.instructor_setting', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_setting_store(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
if ($request->first == 'item_1') {
|
|
||||||
|
|
||||||
$key_found = Setting::where('type', 'instructor_application_note')->exists();
|
|
||||||
if ($key_found) {
|
|
||||||
$data['description'] = $request->instructor_application_note;
|
|
||||||
|
|
||||||
Setting::where('type', 'instructor_application_note')->update($data);
|
|
||||||
} else {
|
|
||||||
$data['type'] = 'instructor_application_note';
|
|
||||||
$data['description'] = $request->instructor_application_note;
|
|
||||||
|
|
||||||
Setting::insert($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$key_founds = Setting::where('type', 'allow_instructor')->exists();
|
|
||||||
if ($key_founds) {
|
|
||||||
$data['description'] = $request->allow_instructor;
|
|
||||||
|
|
||||||
Setting::where('type', 'allow_instructor')->update($data);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$data['type'] = 'allow_instructor';
|
|
||||||
$data['description'] = $request->allow_instructor;
|
|
||||||
|
|
||||||
Setting::insert($data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($request->second == 'item_2') {
|
|
||||||
|
|
||||||
$key_found = Setting::where('type', 'instructor_revenue')->exists();
|
|
||||||
if ($key_found) {
|
|
||||||
$data['description'] = $request->instructor_revenue;
|
|
||||||
|
|
||||||
Setting::where('type', 'instructor_revenue')->update($data);
|
|
||||||
} else {
|
|
||||||
$data['type'] = 'instructor_revenue';
|
|
||||||
$data['description'] = $request->instructor_revenue;
|
|
||||||
|
|
||||||
Setting::insert($data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Instructor setting updated'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function instructor_application()
|
|
||||||
{
|
|
||||||
return view('admin.instructor.application');
|
|
||||||
}
|
|
||||||
public function instructor_application_approve($id)
|
|
||||||
{
|
|
||||||
$query = Application::where('id', $id);
|
|
||||||
$update_status = $query->update(['status' => 1]);
|
|
||||||
if ($update_status) {
|
|
||||||
$user_id = $query->first();
|
|
||||||
User::where('id', $user_id->user_id)->update(['role' => 'instructor']);
|
|
||||||
Session::flash('success', get_phrase('Application approve successfully'));
|
|
||||||
}
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
public function instructor_application_delete($id)
|
|
||||||
{
|
|
||||||
Application::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Application delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
public function instructor_application_download($id)
|
|
||||||
{
|
|
||||||
$path = Application::where('id', $id)->first();
|
|
||||||
|
|
||||||
if (file_exists(public_path($path->document))) {
|
|
||||||
return response()->download(public_path($path->document));
|
|
||||||
} else {
|
|
||||||
Session::flash('error', get_phrase('File does not exists'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function revokeAccess($id)
|
|
||||||
{
|
|
||||||
$user = User::findOrFail($id);
|
|
||||||
|
|
||||||
if ($user->role === 'instructor') {
|
|
||||||
$user->role = 'student';
|
|
||||||
$user->save();
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Instructor has been switched to Student successfully.'));
|
|
||||||
} else {
|
|
||||||
Session::flash('error', get_phrase('This user is not an instructor.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_index()
|
|
||||||
{
|
|
||||||
$query = User::where('role', 'student');
|
|
||||||
if (isset($_GET['search']) && $_GET['search'] != '') {
|
|
||||||
$query = $query->where('name', 'LIKE', '%' . $_GET['search'] . '%')
|
|
||||||
->orWhere('email', 'LIKE', '%' . $_GET['search'] . '%');
|
|
||||||
}
|
|
||||||
$page_data['students'] = $query->paginate(10);
|
|
||||||
return view('admin.student.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_create()
|
|
||||||
{
|
|
||||||
return view('admin.student.create_student');
|
|
||||||
}
|
|
||||||
public function student_edit($id = '')
|
|
||||||
{
|
|
||||||
$page_data['student'] = User::where('id', $id)->first();
|
|
||||||
return view('admin.student.edit_student', $page_data);
|
|
||||||
}
|
|
||||||
public function student_store(Request $request, $id = '')
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required|max:255',
|
|
||||||
'email' => 'required|email|unique:users',
|
|
||||||
'password' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if(get_settings('student_email_verification') != 1){
|
|
||||||
$data['email_verified_at'] = date('Y-m-d H:i:s');
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['paymentkeys'] = json_encode($request->paymentkeys);
|
|
||||||
$data['status'] = '1';
|
|
||||||
|
|
||||||
$data['password'] = Hash::make($request->password);
|
|
||||||
$data['role'] = 'student';
|
|
||||||
|
|
||||||
$data['email_verified_at'] = $request->email_verified == 1 ? now() : null;
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
$path = "uploads/users/student/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::create($data);
|
|
||||||
|
|
||||||
if(get_settings('student_email_verification') == 1) {
|
|
||||||
$user->sendEmailVerificationNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Student add successfully'));
|
|
||||||
|
|
||||||
return redirect()->route('admin.student.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_update(Request $request, $id = '')
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => 'required|max:255',
|
|
||||||
'email' => "required|email|unique:users,email,$id",
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['about'] = $request->about;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['address'] = $request->address;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['paymentkeys'] = json_encode($request->paymentkeys);
|
|
||||||
|
|
||||||
if (isset($request->photo) && $request->hasFile('photo')) {
|
|
||||||
remove_file(User::where('id', $id)->first()->photo);
|
|
||||||
$path = "uploads/users/student/" . nice_file_name($request->name, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $path, 400, null, 200, 200);
|
|
||||||
$data['photo'] = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
User::where('id', $id)->update($data);
|
|
||||||
Session::flash('success', get_phrase('Student update successfully'));
|
|
||||||
return redirect()->route('admin.student.index');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_delete($id)
|
|
||||||
{
|
|
||||||
$threads = MessageThread::where('contact_one', $id)
|
|
||||||
->orWhere('contact_two', $id)
|
|
||||||
->pluck('id');
|
|
||||||
|
|
||||||
if ($threads->isNotEmpty()) {
|
|
||||||
Message::whereIn('thread_id', $threads)->delete();
|
|
||||||
MessageThread::whereIn('id', $threads)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = User::where('id', $id);
|
|
||||||
remove_file($query->first()->photo);
|
|
||||||
$query->delete();
|
|
||||||
return redirect(route('admin.student.index'))->with('success', get_phrase('User deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_enrol()
|
|
||||||
{
|
|
||||||
return view('admin.enroll.course_enrollment');
|
|
||||||
}
|
|
||||||
public function student_get(Request $request)
|
|
||||||
{
|
|
||||||
|
|
||||||
$user = User::where('role', 'student')->where('name', 'LIKE', '%' . $request->searchVal . '%')->get();
|
|
||||||
|
|
||||||
foreach ($user as $row) {
|
|
||||||
$response[] = ['id' => $row->id, 'text' => $row->name];
|
|
||||||
}
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function student_post(Request $request)
|
|
||||||
{
|
|
||||||
for ($i = 0; $i < count($request->user_id); $i++) {
|
|
||||||
for ($j = 0; $j < count($request->course_id); $j++) {
|
|
||||||
$data['user_id'] = $request->user_id[$i];
|
|
||||||
$data['course_id'] = $request->course_id[$j];
|
|
||||||
$data['entry_date'] = time();
|
|
||||||
|
|
||||||
$course_details = $course_details = get_course_info($request->course_id[$j]);
|
|
||||||
|
|
||||||
if ($course_details->expiry_period > 0) {
|
|
||||||
$days = $course_details->expiry_period * 30;
|
|
||||||
$data['expiry_date'] = strtotime("+" . $days . " days");
|
|
||||||
} else {
|
|
||||||
$data['expiry_date'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = Enrollment::where('user_id', $request->user_id[$i])->where('course_id', $request->course_id[$j])->exists();
|
|
||||||
if (!$user) {
|
|
||||||
|
|
||||||
Enrollment::insert($data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Student add successfully'));
|
|
||||||
return redirect()->route('admin.enroll.history');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enroll_history(Request $request)
|
|
||||||
{
|
|
||||||
if ($request->eDateRange) {
|
|
||||||
$date = explode('-', $request->eDateRange);
|
|
||||||
$start_date = strtotime($date[0] . ' 00:00:00');
|
|
||||||
$end_date = strtotime($date[1] . ' 23:59:59');
|
|
||||||
$page_data['start_date'] = $start_date;
|
|
||||||
$page_data['end_date'] = $end_date;
|
|
||||||
$page_data['enroll_history'] = Enrollment::where('entry_date', '>=', $start_date)
|
|
||||||
->where('entry_date', '<=', $end_date)
|
|
||||||
->paginate(10)->appends($request->query());
|
|
||||||
} else {
|
|
||||||
$start_date = strtotime('first day of this month ');
|
|
||||||
$end_date = strtotime('last day of this month');
|
|
||||||
$page_data['start_date'] = $start_date;
|
|
||||||
$page_data['end_date'] = $end_date;
|
|
||||||
$page_data['enroll_history'] = Enrollment::where('entry_date', '>=', $start_date)
|
|
||||||
->where('entry_date', '<=', $end_date)->paginate(10);
|
|
||||||
}
|
|
||||||
return view('admin.enroll.enroll_history', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function enroll_history_delete($id)
|
|
||||||
{
|
|
||||||
|
|
||||||
Enrollment::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Enroll delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manage_profile()
|
|
||||||
{
|
|
||||||
return view('admin.profile.index');
|
|
||||||
}
|
|
||||||
public function manage_profile_update(Request $request)
|
|
||||||
{
|
|
||||||
if ($request->type == 'general') {
|
|
||||||
$profile['name'] = $request->name;
|
|
||||||
$profile['email'] = $request->email;
|
|
||||||
$profile['facebook'] = $request->facebook;
|
|
||||||
$profile['linkedin'] = $request->linkedin;
|
|
||||||
$profile['twitter'] = $request->twitter;
|
|
||||||
$profile['about'] = $request->about;
|
|
||||||
$profile['skills'] = $request->skills;
|
|
||||||
$profile['biography'] = $request->biography;
|
|
||||||
|
|
||||||
if ($request->photo) {
|
|
||||||
if (isset($request->photo) && $request->photo != '') {
|
|
||||||
$profile['photo'] = "uploads/users/admin/" . nice_file_name($request->title, $request->photo->extension());
|
|
||||||
FileUploader::upload($request->photo, $profile['photo'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
User::where('id', auth()->user()->id)->update($profile);
|
|
||||||
} else {
|
|
||||||
$old_pass_check = Auth::attempt(['email' => auth()->user()->email, 'password' => $request->current_password]);
|
|
||||||
|
|
||||||
if (!$old_pass_check) {
|
|
||||||
Session::flash('error', get_phrase('Current password wrong.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->new_password != $request->confirm_password) {
|
|
||||||
Session::flash('error', get_phrase('Confirm password not same'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$password = Hash::make($request->new_password);
|
|
||||||
User::where('id', auth()->user()->id)->update(['password' => $password]);
|
|
||||||
}
|
|
||||||
Session::flash('success', get_phrase('Your changes has been saved.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class ZoomMeetingController extends Controller
|
|
||||||
{
|
|
||||||
public static function createToken()
|
|
||||||
{
|
|
||||||
$clientId = get_settings('zoom_client_id');
|
|
||||||
$clientSecret = get_settings('zoom_client_secret');
|
|
||||||
$accountId = get_settings('zoom_account_id');
|
|
||||||
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Create the Basic Authentication header
|
|
||||||
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
|
|
||||||
|
|
||||||
$ch = curl_init($oauthUrl);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: ' . $authHeader));
|
|
||||||
|
|
||||||
// Execute cURL session and get the response
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
|
|
||||||
// Check if the request was successful (status code 200)
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
curl_close($ch);
|
|
||||||
if ($httpCode == 200) {
|
|
||||||
$oauthResponse = json_decode($response, true);
|
|
||||||
$accessToken = $oauthResponse['access_token'];
|
|
||||||
http_response_code(200);
|
|
||||||
header('Content-Type: application/json');
|
|
||||||
return $accessToken;
|
|
||||||
} else {
|
|
||||||
echo 'OAuth Request Failed with Status Code: ' . $httpCode . PHP_EOL;
|
|
||||||
echo $response . PHP_EOL;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (Exception $e) {
|
|
||||||
echo 'An error occurred: ' . $e->getMessage() . PHP_EOL;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function createMeeting($topic, $time, $duration)
|
|
||||||
{
|
|
||||||
$zoom_account_email = get_settings('zoom_account_email');
|
|
||||||
$token = self::createToken();
|
|
||||||
|
|
||||||
// API Endpoint for creating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
|
|
||||||
|
|
||||||
// Meeting data
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'schedule_for' => $zoom_account_email,
|
|
||||||
'type' => 2,
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($time)),
|
|
||||||
'duration' => $duration,
|
|
||||||
'timezone' => get_settings('timezone'),
|
|
||||||
'settings' => [
|
|
||||||
'approval_type' => 2,
|
|
||||||
'join_before_host' => true,
|
|
||||||
'jbh_time' => 0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make POST request to create meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function updateMeeting($topic, $time, $meetingId)
|
|
||||||
{
|
|
||||||
$token = self::createToken();
|
|
||||||
|
|
||||||
// API Endpoint for updating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Meeting data with updated start time
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($time)),
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make PATCH request to update meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function deleteMeeting($meetingId)
|
|
||||||
{
|
|
||||||
$token = self::createToken();
|
|
||||||
|
|
||||||
// API Endpoint for deleting a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make DELETE request to delete meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function config()
|
|
||||||
{
|
|
||||||
$data['clientId'] = get_settings('zoom_client_id');
|
|
||||||
$data['clientSecret'] = get_settings('zoom_client_secret');
|
|
||||||
$data['accountId'] = get_settings('zoom_account_id');
|
|
||||||
$data['email'] = get_settings('zoom_account_email');
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,179 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\frontend;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Category;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Enrollment;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use App\Models\Section;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\Wishlist;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class CourseController extends Controller
|
|
||||||
{
|
|
||||||
public function index(Request $request, $category = '')
|
|
||||||
{
|
|
||||||
$layout = Session::has('view') ? session('view') : 'grid';
|
|
||||||
$page_data['layout'] = $layout;
|
|
||||||
|
|
||||||
$query = Course::join('users', 'courses.user_id', '=', 'users.id')
|
|
||||||
->select('courses.*', 'users.name as instructor_name', 'users.email as instructor_email', 'users.photo as instructor_image')
|
|
||||||
->where('courses.status', 'active');
|
|
||||||
|
|
||||||
// filter by category
|
|
||||||
if ($category != '') {
|
|
||||||
$category_details = Category::where('slug', $request->category)->first();
|
|
||||||
if ($category_details->parent_id > 0) {
|
|
||||||
$page_data['child_cat'] = $request->category;
|
|
||||||
$query = $query->where('category_id', $category_details->id);
|
|
||||||
} else {
|
|
||||||
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id')->toArray();
|
|
||||||
$sub_cat_id[] = $category_details->id;
|
|
||||||
$query = $query->whereIn('category_id', $sub_cat_id);
|
|
||||||
$page_data['parent_cat'] = $request->category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// searched courses
|
|
||||||
if (request()->has('search')) {
|
|
||||||
$query->where(function ($query) {
|
|
||||||
$query->where('courses.title', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
$query->orWhere('courses.short_description', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
$query->orWhere('courses.level', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
$query->orWhere('courses.meta_keywords', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
$query->orWhere('courses.meta_description', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
$query->orWhere('courses.description', 'LIKE', '%' . request()->input('search') . '%');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by price
|
|
||||||
if (request()->has('price')) {
|
|
||||||
$price = request()->query('price');
|
|
||||||
if ($price == 'paid') {
|
|
||||||
$query = $query->where('is_paid', 1);
|
|
||||||
} elseif ($price == 'discount') {
|
|
||||||
$query = $query->where('discount_flag', 1);
|
|
||||||
} elseif ($price == 'free') {
|
|
||||||
$query = $query->where('is_paid', 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by level
|
|
||||||
if (request()->has('level')) {
|
|
||||||
$level = request()->query('level');
|
|
||||||
$query = $query->where('level', $level);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by language
|
|
||||||
if (request()->has('language')) {
|
|
||||||
$language = request()->query('language');
|
|
||||||
$query = $query->where('language', $language);
|
|
||||||
}
|
|
||||||
|
|
||||||
// filter by rating
|
|
||||||
if (request()->has('rating')) {
|
|
||||||
$rating = request()->query('rating');
|
|
||||||
$query = $query->where('average_rating', $rating);
|
|
||||||
}
|
|
||||||
|
|
||||||
$wishlist = [];
|
|
||||||
if (isset(auth()->user()->id)) {
|
|
||||||
$wishlist = Wishlist::where('user_id', auth()->user()->id)->pluck('course_id')->toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['courses'] = $query->latest('id')->paginate($layout == 'grid' ? 9 : 5)->appends($request->query());
|
|
||||||
$page_data['wishlist'] = $wishlist;
|
|
||||||
$page_data['category_details'] = Category::where('slug', $category)->first();
|
|
||||||
return view('frontend' . '.' . get_frontend_settings('theme') . '.course.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function course_details(Request $request, $slug)
|
|
||||||
{
|
|
||||||
// validate slug
|
|
||||||
if (empty($slug)) {
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// course details
|
|
||||||
$course = Course::where('slug', $slug)->where('status', 'active');
|
|
||||||
if ($course->exists()) {
|
|
||||||
$course_details = $course->first();
|
|
||||||
$page_data['course_details'] = $course_details;
|
|
||||||
$page_data['sections'] = Section::where('course_id', $course_details->id)->orderBy('sort')->get();
|
|
||||||
$page_data['total_lesson'] = Lesson::where('course_id', $course_details->id)->count();
|
|
||||||
$page_data['enroll'] = Enrollment::where('course_id', $course_details->id)->count('user_id');
|
|
||||||
|
|
||||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.course.course_details';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
} else {
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function change_layout(Request $request)
|
|
||||||
{
|
|
||||||
$layout = Session::has('view');
|
|
||||||
if ($layout) {
|
|
||||||
Session::forget('view');
|
|
||||||
}
|
|
||||||
session(['view' => $request->view]);
|
|
||||||
return response()->json(['reload' => true]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public function compare(Request $request)
|
|
||||||
{
|
|
||||||
$course_1 = $request->course_1;
|
|
||||||
$course_2 = $request->course_2;
|
|
||||||
$course_3 = $request->course_3;
|
|
||||||
|
|
||||||
if (isset($course_1) && $course_1 != '') {
|
|
||||||
$course_details_1 = Course::where('status', 'active')->where('slug', $course_1)->first();
|
|
||||||
$page_data['course_details_1'] = $course_details_1;
|
|
||||||
}
|
|
||||||
if (isset($course_2) && $course_2 != '') {
|
|
||||||
$course_details_2 = Course::where('status', 'active')->where('slug', $course_2)->first();
|
|
||||||
$page_data['course_details_2'] = $course_details_2;
|
|
||||||
}
|
|
||||||
if (isset($course_3) && $course_3 != '') {
|
|
||||||
$course_details_3 = Course::where('status', 'active')->where('slug', $course_3)->first();
|
|
||||||
$page_data['course_details_3'] = $course_details_3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($course_1 == '' && $course_2 == '' && $course_3 == '') {
|
|
||||||
$page_data['course_details'] = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('frontend.course.compare', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function comparewith($course_1 = '', $course_2 = '', $course_3 = '')
|
|
||||||
{
|
|
||||||
|
|
||||||
$response = array();
|
|
||||||
$result = Course::join('users', 'courses.user_id', 'users.id')
|
|
||||||
->select('course.id as id', 'course.title as title', 'users.first_name as first_name', 'users.last_name as last_name')
|
|
||||||
->where('course.id', '!=', $course_1)
|
|
||||||
->where('course.id', '!=', $course_2)
|
|
||||||
->where('course.id', '!=', $course_3)
|
|
||||||
->where('course.status', 'active')
|
|
||||||
|
|
||||||
->like('course.title', $_GET['searchVal'])
|
|
||||||
->or_like('short_description', $_GET['searchVal'])
|
|
||||||
->or_like('first_name', $_GET['searchVal'])
|
|
||||||
->or_like('last_name', $_GET['searchVal'])
|
|
||||||
|
|
||||||
->take(100)
|
|
||||||
->get();
|
|
||||||
|
|
||||||
foreach ($result as $key => $row) {
|
|
||||||
$response[] = ['id' => $row->id, 'text' => $row->title . ' (' . get_phrase('Creator') . ': ' . $row->first_name];
|
|
||||||
}
|
|
||||||
echo json_encode($response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,208 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\frontend;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Blog;
|
|
||||||
use App\Models\Builder_page;
|
|
||||||
use App\Models\Category;
|
|
||||||
use App\Models\Certificate;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Message;
|
|
||||||
use App\Models\Message_code;
|
|
||||||
use App\Models\Review;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
|
||||||
use DB;
|
|
||||||
|
|
||||||
use App\Http\Controllers\NewsletterController;
|
|
||||||
|
|
||||||
class HomeController extends Controller
|
|
||||||
{
|
|
||||||
function homepage_switcher($id){
|
|
||||||
session(['home' => $id]);
|
|
||||||
return redirect(route('home'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
if(session('home')){
|
|
||||||
$page_builder = Builder_page::where('id', session('home'))->first();
|
|
||||||
}else{
|
|
||||||
$page_builder = Builder_page::where('status', 1)->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($page_builder && $page_builder->is_permanent == 1) {
|
|
||||||
$page_data['blogs'] = Blog::where('status', 1)->orderBy('is_popular', 'desc')->orderBy('id', 'desc')->take(3)->get();
|
|
||||||
$page_data['reviews'] = Review::all();
|
|
||||||
return view('components.home_permanent_templates.' . $page_builder->identifier, $page_data);
|
|
||||||
} else {
|
|
||||||
$page_data['instructor'] = User::join('courses', 'users.id', 'courses.user_id')
|
|
||||||
->select('users.*', 'courses.title as course_title')
|
|
||||||
->get()->unique()->take(4);
|
|
||||||
|
|
||||||
$page_data['blogs'] = Blog::where('status', 1)->orderBy('is_popular', 'desc')->orderBy('id', 'desc')->take(3)->get();
|
|
||||||
$page_data['category'] = Category::take(8)->get();
|
|
||||||
|
|
||||||
$view_path = 'frontend' . '.' . get_frontend_settings('theme') . '.home.index';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function download_certificate($identifier)
|
|
||||||
{
|
|
||||||
$certificate = Certificate::where('identifier', $identifier);
|
|
||||||
if ($certificate->count() > 0) {
|
|
||||||
$qr_code_content_value = route('certificate', ['identifier' => $identifier]);
|
|
||||||
$qrcode = QrCode::size(300)->generate($qr_code_content_value);
|
|
||||||
|
|
||||||
$page_data['certificate'] = $certificate->first();
|
|
||||||
$page_data['qrcode'] = $qrcode;
|
|
||||||
return view('curriculum.certificate.download', $page_data);
|
|
||||||
} else {
|
|
||||||
return redirect(route('home'))->with('error', get_phrase('Certificate not found at this url'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_watch_history_with_duration(Request $request)
|
|
||||||
{
|
|
||||||
$userId = auth()->user()->id; // Get the logged-in user's ID
|
|
||||||
$courseProgress = 0;
|
|
||||||
$isCompleted = 0;
|
|
||||||
|
|
||||||
// Retrieve and sanitize input data
|
|
||||||
$courseId = htmlspecialchars($request->input('course_id'));
|
|
||||||
$lessonId = htmlspecialchars($request->input('lesson_id'));
|
|
||||||
$currentDuration = htmlspecialchars($request->input('current_duration'));
|
|
||||||
|
|
||||||
// Fetch current watch history record
|
|
||||||
$currentHistory = DB::table('watch_durations')
|
|
||||||
->where([
|
|
||||||
'watched_course_id' => $courseId,
|
|
||||||
'watched_lesson_id' => $lessonId,
|
|
||||||
'watched_student_id' => $userId,
|
|
||||||
])
|
|
||||||
->first();
|
|
||||||
|
|
||||||
// Fetch course details
|
|
||||||
$courseDetails = DB::table('courses')->where('id', $courseId)->first();
|
|
||||||
$dripContentSettings = json_decode($courseDetails->drip_content_settings, true);
|
|
||||||
|
|
||||||
if ($currentHistory) {
|
|
||||||
$watchedDurationArr = json_decode($currentHistory->watched_counter, true);
|
|
||||||
if (!is_array($watchedDurationArr)) $watchedDurationArr = [];
|
|
||||||
|
|
||||||
if (!in_array($currentDuration, $watchedDurationArr)) {
|
|
||||||
array_push($watchedDurationArr, $currentDuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
$watchedDurationJson = json_encode($watchedDurationArr);
|
|
||||||
|
|
||||||
DB::table('watch_durations')
|
|
||||||
->where([
|
|
||||||
'watched_course_id' => $courseId,
|
|
||||||
'watched_lesson_id' => $lessonId,
|
|
||||||
'watched_student_id' => $userId,
|
|
||||||
])
|
|
||||||
->update([
|
|
||||||
'watched_counter' => $watchedDurationJson,
|
|
||||||
'current_duration' => $currentDuration,
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$watchedDurationArr = [$currentDuration];
|
|
||||||
DB::table('watch_durations')->insert([
|
|
||||||
'watched_course_id' => $courseId,
|
|
||||||
'watched_lesson_id' => $lessonId,
|
|
||||||
'watched_student_id' => $userId,
|
|
||||||
'current_duration' => $currentDuration,
|
|
||||||
'watched_counter' => json_encode($watchedDurationArr),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($courseDetails->enable_drip_content != 1) {
|
|
||||||
return response()->json([
|
|
||||||
'lesson_id' => $lessonId,
|
|
||||||
'course_progress' => null,
|
|
||||||
'is_completed' => null
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch lesson details for duration calculations
|
|
||||||
$lessonTotalDuration = DB::table('lessons')->where('id', $lessonId)->value('duration');
|
|
||||||
$lessonTotalDurationArr = explode(':', $lessonTotalDuration);
|
|
||||||
$lessonTotalSeconds = ($lessonTotalDurationArr[0] * 3600) + ($lessonTotalDurationArr[1] * 60) + $lessonTotalDurationArr[2];
|
|
||||||
$currentTotalSeconds = count($watchedDurationArr) * 5; // Assuming each increment represents 5 seconds
|
|
||||||
|
|
||||||
// Drip content completion logic
|
|
||||||
if ($dripContentSettings['lesson_completion_role'] == 'duration') {
|
|
||||||
if ($currentTotalSeconds >= $dripContentSettings['minimum_duration']) {
|
|
||||||
$isCompleted = 1;
|
|
||||||
} elseif (($currentTotalSeconds + 4) >= $lessonTotalSeconds) {
|
|
||||||
$isCompleted = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$requiredDuration = ($lessonTotalSeconds / 100) * $dripContentSettings['minimum_percentage'];
|
|
||||||
if ($currentTotalSeconds >= $requiredDuration) {
|
|
||||||
$isCompleted = 1;
|
|
||||||
} elseif (($currentTotalSeconds + 4) >= $lessonTotalSeconds) {
|
|
||||||
$isCompleted = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update course progress if the lesson is completed
|
|
||||||
if ($isCompleted == 1) {
|
|
||||||
$watchHistory = DB::table('watch_histories')
|
|
||||||
->where([
|
|
||||||
'course_id' => $courseId,
|
|
||||||
'student_id' => $userId,
|
|
||||||
])
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($watchHistory) {
|
|
||||||
$lessonIds = json_decode($watchHistory->completed_lesson, true);
|
|
||||||
$courseProgress = $watchHistory->course_progress;
|
|
||||||
|
|
||||||
if (!is_array($lessonIds)) $lessonIds = [];
|
|
||||||
|
|
||||||
if (!in_array($lessonId, $lessonIds)) {
|
|
||||||
array_push($lessonIds, $lessonId);
|
|
||||||
$totalLesson = DB::table('lessons')->where('course_id', $courseId)->count();
|
|
||||||
$courseProgress = (100 / $totalLesson) * count($lessonIds);
|
|
||||||
|
|
||||||
$completedDate = ($courseProgress >= 100 && !$watchHistory->completed_date)
|
|
||||||
? time()
|
|
||||||
: $watchHistory->completed_date;
|
|
||||||
|
|
||||||
DB::table('watch_histories')
|
|
||||||
->where('id', $watchHistory->id)
|
|
||||||
->update([
|
|
||||||
'course_progress' => $courseProgress,
|
|
||||||
'completed_lesson' => json_encode($lessonIds),
|
|
||||||
'completed_date' => $completedDate,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the response
|
|
||||||
return response()->json([
|
|
||||||
'lesson_id' => $lessonId,
|
|
||||||
'course_progress' => round($courseProgress),
|
|
||||||
'is_completed' => $isCompleted,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendEmailToAssignedAddresses()
|
|
||||||
{
|
|
||||||
// Accessing the method from NewsletterController
|
|
||||||
$newsletterController = new NewsletterController();
|
|
||||||
$response = $newsletterController->sendEmailToAssignedAddresses();
|
|
||||||
|
|
||||||
if ($response) {
|
|
||||||
return response($response);
|
|
||||||
}
|
|
||||||
return response('No response', 404); // Default response if no data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\frontend;
|
|
||||||
use App\Models\Knowledge_base_topick;
|
|
||||||
use App\Models\Knowledge_base;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
|
|
||||||
class KnowledgeBaseTopicController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
|
|
||||||
$articles = Knowledge_base::orderBy('updated_at', 'desc')->paginate(10);
|
|
||||||
|
|
||||||
return view('frontend.default.knowledge_base_topics.index', ['articles'=> $articles]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for creating a new resource.
|
|
||||||
*/
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*/
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the specified resource.
|
|
||||||
*/
|
|
||||||
public function show(string $id)
|
|
||||||
{
|
|
||||||
$query = Knowledge_base_topick::where('id', $id)->first();
|
|
||||||
|
|
||||||
if($query){
|
|
||||||
|
|
||||||
$title =Knowledge_base::where('id',$query->knowledge_base_id)->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$query) {
|
|
||||||
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->route('knowledge.base.topicks');
|
|
||||||
}
|
|
||||||
return view('frontend.default.knowledge_base_topics.article_single', ['title'=> $title,'article'=> $query]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*/
|
|
||||||
public function edit(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*/
|
|
||||||
public function update(Request $request, string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy(string $id)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,350 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Bootcamp;
|
|
||||||
use App\Models\BootcampCategory;
|
|
||||||
use App\Models\BootcampModule;
|
|
||||||
use App\Models\BootcampPurchase;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\SeoField;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class BootcampController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$query = Bootcamp::join('bootcamp_categories', 'bootcamps.category_id', 'bootcamp_categories.id')
|
|
||||||
->select('bootcamps.*', 'bootcamp_categories.title as category', 'bootcamp_categories.slug as category_slug')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id);
|
|
||||||
|
|
||||||
if (request()->has('search')) {
|
|
||||||
$query = $query->where('bootcamps.title', 'LIKE', "%" . request()->query('search') . "%");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request()->has('category') && request()->query('category') != 'all') {
|
|
||||||
$category = BootcampCategory::where('slug', request()->query('category'))->first();
|
|
||||||
$query = $query->where('bootcamps.category_id', $category->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request()->has('status') && request()->query('status') != 'all') {
|
|
||||||
$status = request()->query('status') == 'active' ? 1 : 0;
|
|
||||||
$query = $query->where('bootcamps.status', $status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request()->has('instructor') && request()->query('instructor') != 'all') {
|
|
||||||
$query = $query->where('bootcamps.user_id', request()->query('instructor'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (request()->has('price') && request()->query('price') != 'all') {
|
|
||||||
$price = request()->query('price');
|
|
||||||
$value = 1;
|
|
||||||
if ($price == 'free') {
|
|
||||||
$column = 'is_paid';
|
|
||||||
$value = 0;
|
|
||||||
} elseif ($price == 'discounted') {
|
|
||||||
$column = 'discount_flag';
|
|
||||||
} elseif ($price == 'paid') {
|
|
||||||
$column = 'is_paid';
|
|
||||||
}
|
|
||||||
$query = $query->where('bootcamps.' . $column, $value);
|
|
||||||
}
|
|
||||||
$page_data['bootcamps'] = $query->paginate(20)->appends(request()->query());
|
|
||||||
return view('instructor.bootcamp.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
return view('instructor.bootcamp.create');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit($id)
|
|
||||||
{
|
|
||||||
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id)->first();
|
|
||||||
if (! $bootcamp) {
|
|
||||||
Session::flash('success', get_phrase('Data not found.'));
|
|
||||||
return redirect()->route('instructor.bootcamps');
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['bootcamp_details'] = $bootcamp;
|
|
||||||
$page_data['modules'] = BootcampModule::where('bootcamp_id', $id)->get();
|
|
||||||
return view('instructor.bootcamp.edit', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'description' => 'required|string',
|
|
||||||
'category_id' => 'required',
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
];
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$title = Bootcamp::where('user_id', auth()->user()->id)->where('title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['publish_date'] = strtotime($request->publish_date);
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
$data['status'] = 1;
|
|
||||||
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$insert_id = Bootcamp::insertGetId($data);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Bootcamp has been created.'));
|
|
||||||
return redirect()->route('instructor.bootcamp.edit', [$insert_id, 'tab' => 'curriculum']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
|
|
||||||
if ($bootcamp->doesntExist()) {
|
|
||||||
Session::flash('success', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$bootcamp->delete();
|
|
||||||
Session::flash('success', get_phrase('Bootcamp has been deleted.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$query = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
|
|
||||||
|
|
||||||
if ($query->doesntExist() || $request->tab == '') {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$rules = $data = [];
|
|
||||||
if ($request->tab == 'basic') {
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'description' => 'required|string',
|
|
||||||
'category_id' => 'required',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['publish_date'] = strtotime($request->publish_date);
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
|
|
||||||
$title = Bootcamp::where('user_id', auth()->user()->id)
|
|
||||||
->where('id', '!=', $id)
|
|
||||||
->where('title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'pricing') {
|
|
||||||
$rules = [
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'info') {
|
|
||||||
$rules = [
|
|
||||||
'requirements' => 'array',
|
|
||||||
'outcomes' => 'array',
|
|
||||||
'faqs' => 'array',
|
|
||||||
];
|
|
||||||
|
|
||||||
//Remove empty value by using array filter function
|
|
||||||
$data['requirements'] = json_encode(array_filter($request->requirements, fn($value) => ! is_null($value) && $value !== ''));
|
|
||||||
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn($value) => ! is_null($value) && $value !== ''));
|
|
||||||
|
|
||||||
$faqs = [];
|
|
||||||
foreach ($request->faq_title as $key => $title) {
|
|
||||||
if ($title != '') {
|
|
||||||
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['faqs'] = json_encode($faqs);
|
|
||||||
} elseif ($request->tab == 'media') {
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/bootcamp/thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail']);
|
|
||||||
remove_file($query->first()->thumbnail);
|
|
||||||
}
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'seo') {
|
|
||||||
$bootcamp_details = $query->first();
|
|
||||||
$SeoField = SeoField::where('name_route', 'bootcamp.details')->where('bootcamp_id', $bootcamp_details->id)->first();
|
|
||||||
|
|
||||||
$seo_data['bootcamp_id'] = $id;
|
|
||||||
$seo_data['route'] = 'Bootcamp Details';
|
|
||||||
$seo_data['name_route'] = 'bootcamp.details';
|
|
||||||
$seo_data['meta_title'] = $request->meta_title;
|
|
||||||
$seo_data['meta_description'] = $request->meta_description;
|
|
||||||
$seo_data['meta_robot'] = $request->meta_robot;
|
|
||||||
$seo_data['canonical_url'] = $request->canonical_url;
|
|
||||||
$seo_data['custom_url'] = $request->custom_url;
|
|
||||||
$seo_data['json_ld'] = $request->json_ld;
|
|
||||||
$seo_data['og_title'] = $request->og_title;
|
|
||||||
$seo_data['og_description'] = $request->og_description;
|
|
||||||
$seo_data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$seo_data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
$meta_keywords_arr = json_decode($request->meta_keywords, true);
|
|
||||||
$meta_keywords = '';
|
|
||||||
if (is_array($meta_keywords_arr)) {
|
|
||||||
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
|
|
||||||
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
|
|
||||||
}
|
|
||||||
$seo_data['meta_keywords'] = $meta_keywords;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->og_image) {
|
|
||||||
$originalFileName = $bootcamp_details->id . '-' . $request->og_image->getClientOriginalName();
|
|
||||||
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
|
|
||||||
// Move the file to the destination path
|
|
||||||
FileUploader::upload($request->og_image, $destinationPath, 600);
|
|
||||||
$seo_data['og_image'] = $destinationPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($SeoField) {
|
|
||||||
if ($request->og_image) {
|
|
||||||
remove_file($SeoField->og_image);
|
|
||||||
}
|
|
||||||
SeoField::where('name_route', 'bootcamp.details')->where('bootcamp_id', $bootcamp_details->id)->update($seo_data);
|
|
||||||
} else {
|
|
||||||
SeoField::insert($seo_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->update($data);
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
// return ['success' => get_phrase('Course updated successfully')];
|
|
||||||
|
|
||||||
//for normal form submission
|
|
||||||
Session::flash('success', get_phrase('Bootcamp has been updated successfully.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function duplicate($id)
|
|
||||||
{
|
|
||||||
$bootcamp = Bootcamp::where('id', $id);
|
|
||||||
if ($bootcamp->doesntExist()) {
|
|
||||||
Session::flash('success', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$bootcamp = $bootcamp->first()->toArray();
|
|
||||||
$bootcamp['title'] = $bootcamp['title'] . ' copy';
|
|
||||||
$bootcamp['slug'] = slugify($bootcamp['title']);
|
|
||||||
$bootcamp['user_id'] = auth()->user()->id;
|
|
||||||
$bootcamp['status'] = 1;
|
|
||||||
unset($bootcamp['id'], $bootcamp['created_at'], $bootcamp['updated_at']);
|
|
||||||
|
|
||||||
$insert_id = Bootcamp::insertGetId($bootcamp);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Bootcamp has been duplicated.'));
|
|
||||||
return redirect()->route('instructor.bootcamp.edit', [$insert_id, 'tab' => 'basic']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function status($id)
|
|
||||||
{
|
|
||||||
$bootcamp = Bootcamp::where('id', $id)->where('user_id', auth()->user()->id);
|
|
||||||
if ($bootcamp->doesntExist()) {
|
|
||||||
$response = [
|
|
||||||
'error' => get_phrase('Data not found.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = $bootcamp->first()->status ? 0 : 1;
|
|
||||||
Bootcamp::where('id', $id)->update(['status' => $status]);
|
|
||||||
|
|
||||||
$response = [
|
|
||||||
'success' => get_phrase('Status has been updated.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function purchase_history()
|
|
||||||
{
|
|
||||||
$page_data['purchases'] = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select(
|
|
||||||
'bootcamp_purchases.*',
|
|
||||||
'bootcamps.user_id as author',
|
|
||||||
'bootcamps.title',
|
|
||||||
'bootcamps.slug',
|
|
||||||
'bootcamps.price as amount',
|
|
||||||
)
|
|
||||||
->latest('bootcamp_purchases.id')->paginate(20)->appends(request()->query());
|
|
||||||
|
|
||||||
return view('instructor.bootcamp.purchase_history', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function invoice($id)
|
|
||||||
{
|
|
||||||
$invoice = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_purchases.id', $id)
|
|
||||||
->select(
|
|
||||||
'bootcamp_purchases.*',
|
|
||||||
'bootcamps.title',
|
|
||||||
'bootcamps.slug',
|
|
||||||
)->first();
|
|
||||||
|
|
||||||
if (! $invoice) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['invoice'] = $invoice;
|
|
||||||
return view('instructor.bootcamp.invoice', $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,263 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Controllers\ZoomMeetingController;
|
|
||||||
use App\Models\BootcampLiveClass;
|
|
||||||
use App\Models\BootcampModule;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class BootcampLiveClassController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
date_default_timezone_set('Asia/Dhaka');
|
|
||||||
}
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'date' => 'required|date',
|
|
||||||
'start_time' => 'required|string',
|
|
||||||
'end_time' => 'required|string|after:start_time',
|
|
||||||
'module_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check selected module
|
|
||||||
$module = BootcampModule::where('id', $request->module_id)->first();
|
|
||||||
if (! $module) {
|
|
||||||
Session::flash('error', get_phrase('Module does not exist.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// process class schedule
|
|
||||||
$start = $request->date . ' ' . $request->start_time;
|
|
||||||
$start_timestamp = strtotime($start);
|
|
||||||
$end = $request->date . ' ' . $request->end_time;
|
|
||||||
$end_timestamp = strtotime($end);
|
|
||||||
|
|
||||||
// check module and class schedule
|
|
||||||
if ($module->restriction) {
|
|
||||||
if ($module->restriction == 1 && $start_timestamp < $module->publish_date) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
if ($module->restriction == 2 && (($start_timestamp < $module->publish_date || $start_timestamp > $module->expiry_date) && ($end_timestamp < $module->publish_date || $end_timestamp > $module->expiry_date))) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check duplicate title for same bootcamp id
|
|
||||||
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_modules.id', $request->module_id)
|
|
||||||
->where('bootcamp_live_classes.title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['module_id'] = $request->module_id;
|
|
||||||
$data['start_time'] = $start_timestamp;
|
|
||||||
$data['end_time'] = $end_timestamp;
|
|
||||||
|
|
||||||
// Calculate the difference in seconds
|
|
||||||
$difference_in_seconds = $data['end_time'] - $data['start_time'];
|
|
||||||
|
|
||||||
// Convert the difference to minutes
|
|
||||||
$difference_in_minutes = $difference_in_seconds / 60;
|
|
||||||
|
|
||||||
$joiningData = ZoomMeetingController::createMeeting($request->title, $start_timestamp, $difference_in_minutes);
|
|
||||||
$joiningInfoArr = json_decode($joiningData, true);
|
|
||||||
|
|
||||||
if (array_key_exists('code', $joiningInfoArr) && $joiningInfoArr) {
|
|
||||||
return redirect(route('instructor.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']))->with('error', get_phrase($joiningInfoArr['message']));
|
|
||||||
}
|
|
||||||
$data['provider'] = 'zoom';
|
|
||||||
$data['joining_data'] = $joiningData;
|
|
||||||
|
|
||||||
BootcampLiveClass::insert($data);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Live class has been created.'));
|
|
||||||
return redirect()->route('instructor.bootcamp.edit', ['id' => $module->bootcamp_id, 'tab' => 'curriculum']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$validator = Validator::make($request->all(), [
|
|
||||||
'title' => 'required|string',
|
|
||||||
'start_time' => 'required',
|
|
||||||
'end_time' => 'required',
|
|
||||||
'module_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamp_live_classes.module_id', $request->module_id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamp_modules.restriction', 'bootcamp_modules.publish_date', 'bootcamp_modules.expiry_date')
|
|
||||||
->first();
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// process class schedule
|
|
||||||
$start = $request->date . ' ' . $request->start_time;
|
|
||||||
$start_timestamp = strtotime($start);
|
|
||||||
$end = $request->date . ' ' . $request->end_time;
|
|
||||||
$end_timestamp = strtotime($end);
|
|
||||||
|
|
||||||
// check module and class schedule
|
|
||||||
if ($class->restriction) {
|
|
||||||
if ($class->restriction == 1 && $start_timestamp < $class->publish_date) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
if ($class->restriction == 2 && (($start_timestamp < $class->publish_date || $start_timestamp > $class->expiry_date) && ($end_timestamp < $class->publish_date || $end_timestamp > $class->expiry_date))) {
|
|
||||||
Session::flash('error', get_phrase('Please set class schedule properly.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check duplicate title for same bootcamp id
|
|
||||||
$title = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_modules.id', $request->module_id)
|
|
||||||
->where('bootcamp_live_classes.id', '!=', $id)
|
|
||||||
->where('bootcamp_live_classes.title', $request->title)->first();
|
|
||||||
if ($title) {
|
|
||||||
Session::flash('error', get_phrase('This title has been taken.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($class->start_time != $start_timestamp || $class->end_time != $end_timestamp) {
|
|
||||||
$data['force_stop'] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['module_id'] = $request->module_id;
|
|
||||||
$data['start_time'] = $start_timestamp;
|
|
||||||
$data['end_time'] = $end_timestamp;
|
|
||||||
|
|
||||||
if ($class->provider == 'zoom') {
|
|
||||||
$oldMeetingData = json_decode($class->joining_data, true);
|
|
||||||
ZoomMeetingController::updateMeeting($request->title, $request->start_time, $oldMeetingData['id']);
|
|
||||||
$oldMeetingData["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->start_time));
|
|
||||||
$oldMeetingData["topic"] = $request->class_topic;
|
|
||||||
$data['joining_data'] = json_encode($oldMeetingData);
|
|
||||||
}
|
|
||||||
|
|
||||||
$class->update($data);
|
|
||||||
|
|
||||||
Session::flash('success', get_phrase('Live class has been updated.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id);
|
|
||||||
if ($class->doesntExist()) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$meetingData = $class->value('joining_data');
|
|
||||||
if ($meetingData) {
|
|
||||||
$oldMeetingData = json_decode($meetingData, true);
|
|
||||||
ZoomMeetingController::deleteMeeting($oldMeetingData['id']);
|
|
||||||
}
|
|
||||||
BootcampLiveClass::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Live class has been deleted.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function join_class($slug)
|
|
||||||
{
|
|
||||||
$current_time = time();
|
|
||||||
$extended_time = $current_time + (60 * 15);
|
|
||||||
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.slug', $slug)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id', 'bootcamps.user_id as host_id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Class not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
$page_data['class'] = $class;
|
|
||||||
$page_data['user'] = get_user_info($class->host_id);
|
|
||||||
$page_data['is_host'] = 1;
|
|
||||||
return view('bootcamp_online_class.index', $page_data);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($class->joining_data, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop_class($id)
|
|
||||||
{
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_live_classes.id', $id)
|
|
||||||
->where('bootcamps.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$class->update(['force_stop' => 1]);
|
|
||||||
Session::flash('success', get_phrase('Class has been ended.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sort(Request $request)
|
|
||||||
{
|
|
||||||
$classes = json_decode($request->itemJSON);
|
|
||||||
foreach ($classes as $key => $value) {
|
|
||||||
$updater = $key + 1;
|
|
||||||
BootcampLiveClass::where('id', $value)->update(['sort' => $updater]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'status' => true,
|
|
||||||
'success' => get_phrase('Classes sorted successfully'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,482 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Category;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\Section;
|
|
||||||
use App\Models\SeoField;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
use Yajra\DataTables\Facades\DataTables;
|
|
||||||
|
|
||||||
class CourseController extends Controller
|
|
||||||
{
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
$category = 'all';
|
|
||||||
$status = 'all';
|
|
||||||
$instructor = 'all';
|
|
||||||
$price = 'all';
|
|
||||||
|
|
||||||
$query = Course::where('user_id', auth()->user()->id);
|
|
||||||
|
|
||||||
if (isset($request->category) && $request->category != '' && $request->category != 'all') {
|
|
||||||
|
|
||||||
$category_details = Category::where('slug', $request->category)->first();
|
|
||||||
if ($category_details->parent_id == 0) {
|
|
||||||
$sub_cat_id = Category::where('parent_id', $category_details->id)->pluck('id');
|
|
||||||
$query = $query->whereIn('category_id', $sub_cat_id->toArray());
|
|
||||||
$page_data['parent_cat'] = $request->category;
|
|
||||||
} else {
|
|
||||||
$page_data['child_cat'] = $request->category;
|
|
||||||
$query = $query->where('category_id', $category_details->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// search filter
|
|
||||||
if (isset($_GET['search']) && $_GET['search'] != '') {
|
|
||||||
$query = $query->where('title', 'LIKE', '%' . $_GET['search'] . '%');
|
|
||||||
}
|
|
||||||
|
|
||||||
// selected price
|
|
||||||
if (isset($_GET['price']) && $_GET['price'] != '' && $_GET['price'] != 'all') {
|
|
||||||
$search_price = 2;
|
|
||||||
if ($_GET['price'] == 'free') {
|
|
||||||
$search_price = 0;
|
|
||||||
} elseif ($_GET['price'] == 'paid') {
|
|
||||||
$search_price = 1;
|
|
||||||
}
|
|
||||||
$query = $query->where('is_paid', $search_price);
|
|
||||||
$price = $_GET['price'];
|
|
||||||
}
|
|
||||||
// selected instructor
|
|
||||||
if (isset($_GET['instructor']) && $_GET['instructor'] != '' && $_GET['instructor'] != 'all') {
|
|
||||||
$query = $query->where('user_id', $_GET['instructor']);
|
|
||||||
$instructor = $_GET['instructor'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// status filter
|
|
||||||
if (isset($_GET['status']) && $_GET['status'] != '' && $_GET['status'] != 'all') {
|
|
||||||
|
|
||||||
if ($_GET['status'] == 'active') {
|
|
||||||
$search_status = 'active';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'inactive') {
|
|
||||||
$search_status = 'inactive';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'pending') {
|
|
||||||
$search_status = 'pending';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'private') {
|
|
||||||
$search_status = 'private';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'upcoming') {
|
|
||||||
$search_status = 'upcoming';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
} elseif ($_GET['status'] == 'draft') {
|
|
||||||
$search_status = 'draft';
|
|
||||||
$query = $query->where('status', $search_status);
|
|
||||||
}
|
|
||||||
$status = $_GET['status'];
|
|
||||||
}
|
|
||||||
$page_data['status'] = $status;
|
|
||||||
$page_data['instructor'] = $instructor;
|
|
||||||
$page_data['price'] = $price;
|
|
||||||
$page_data['courses'] = $query->orderBy('id', 'desc')->paginate(20)->appends(request()->query());
|
|
||||||
$page_data['pending_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'pending')->count();
|
|
||||||
$page_data['active_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'active')->count();
|
|
||||||
$page_data['upcoming_courses'] = Course::where('user_id', auth()->user()->id)->where('status', 'upcoming')->count();
|
|
||||||
$page_data['paid_courses'] = Course::where('user_id', auth()->user()->id)->where('is_paid', 1)->count();
|
|
||||||
$page_data['free_courses'] = Course::where('user_id', auth()->user()->id)->where('is_paid', 0)->count();
|
|
||||||
|
|
||||||
return view('instructor.course.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create()
|
|
||||||
{
|
|
||||||
return view('instructor.course.create');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|max:255',
|
|
||||||
'category_id' => 'required|numeric|min:1',
|
|
||||||
'course_type' => 'required|in:general,scorm',
|
|
||||||
'level' => 'required|in:everyone,beginner,intermediate,advanced',
|
|
||||||
'language' => 'required',
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
'requirements' => 'array',
|
|
||||||
'outcomes' => 'array',
|
|
||||||
'faqs' => 'array',
|
|
||||||
'instructors' => 'required|array|min:1',
|
|
||||||
];
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
if ($validator->fails()) {
|
|
||||||
//return form validation error as json formate for ajaxForm submission
|
|
||||||
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
|
|
||||||
}
|
|
||||||
//for normal form submission
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title);
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['course_type'] = $request->course_type;
|
|
||||||
$data['status'] = 'pending';
|
|
||||||
$data['level'] = $request->level;
|
|
||||||
$data['language'] = strtolower($request->language);
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
|
|
||||||
$data['enable_drip_content'] = $request->enable_drip_content;
|
|
||||||
|
|
||||||
|
|
||||||
$drip_content_settings = '{"lesson_completion_role":"percentage","minimum_duration":15,"minimum_percentage":"30","locked_lesson_message":"<h3 xss="removed" style="text-align: center; "><span xss="removed"><strong>Permission denied!<\/strong><\/span><\/h3><p xss="removed" style="text-align: center; "><span xss="removed">This course supports drip content, so you must complete the previous lessons.<\/span><\/p>"}';
|
|
||||||
|
|
||||||
$data['drip_content_settings'] = $drip_content_settings;
|
|
||||||
|
|
||||||
$meta_keywords = '';
|
|
||||||
$meta_keywords_arr = json_decode($request->meta_keywords, true);
|
|
||||||
if (is_array($meta_keywords_arr)) {
|
|
||||||
foreach ($meta_keywords_arr as $key => $keyword) {
|
|
||||||
if ($key > 0) {
|
|
||||||
$meta_keywords .= ',' . $keyword['value'];
|
|
||||||
} else {
|
|
||||||
$meta_keywords .= $keyword['value'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['meta_keywords'] = $meta_keywords;
|
|
||||||
$data['meta_description'] = $request->meta_description;
|
|
||||||
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
|
|
||||||
//Course expiry period
|
|
||||||
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
|
|
||||||
$data['expiry_period'] = $request->number_of_month;
|
|
||||||
} else {
|
|
||||||
$data['expiry_period'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Remove empty value by using array filter function
|
|
||||||
if (isset($request->requirements) && $request->requirements != '') {
|
|
||||||
|
|
||||||
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
}
|
|
||||||
if (isset($request->outcomes) && $request->outcomes != '') {
|
|
||||||
|
|
||||||
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($request->faq_title) && $request->faq_title != '') {
|
|
||||||
|
|
||||||
$faqs = [];
|
|
||||||
foreach ($request->faq_title as $key => $title) {
|
|
||||||
if ($title != '') {
|
|
||||||
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['faqs'] = json_encode($faqs);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['instructor_ids'] = json_encode($request->instructors);
|
|
||||||
$data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->banner) {
|
|
||||||
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
|
|
||||||
FileUploader::upload($request->banner, $data['banner'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->preview) {
|
|
||||||
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
|
|
||||||
FileUploader::upload($request->preview, $data['preview']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$course_id = Course::insertGetId($data);
|
|
||||||
Course::where('id', $course_id)->update(['slug' => slugify($request->title . '-' . $course_id)]);
|
|
||||||
|
|
||||||
// //For ajax form submission
|
|
||||||
Session::flash('success', get_phrase('Course added successfully'));
|
|
||||||
return [
|
|
||||||
'redirectTo' => route('instructor.course.edit', ['id' => $course_id]),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function edit(Request $request, $course_id = "")
|
|
||||||
{
|
|
||||||
$data['course_details'] = Course::where('id', $course_id)->first();
|
|
||||||
$data['sections'] = Section::where('course_id', $course_id)->orderBy('sort')->get();
|
|
||||||
return view('instructor.course.edit', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$query = Course::where('id', $id);
|
|
||||||
|
|
||||||
if ($request->tab == '') {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$rules = $data = [];
|
|
||||||
if ($request->tab == 'basic') {
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|max:255',
|
|
||||||
'category_id' => 'required|numeric|min:1',
|
|
||||||
'level' => 'required|in:everyone,beginner,intermediate,advanced',
|
|
||||||
'language' => 'required',
|
|
||||||
'status' => 'required|in:active,pending,draft,private,upcoming,inactive',
|
|
||||||
'instructors' => 'required|array|min:1',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['title'] = $request->title;
|
|
||||||
$data['slug'] = slugify($request->title . '-' . $id);
|
|
||||||
$data['short_description'] = $request->short_description;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['level'] = $request->level;
|
|
||||||
$data['language'] = strtolower($request->language);
|
|
||||||
$data['status'] = $request->status;
|
|
||||||
$data['instructor_ids'] = json_encode($request->instructors);
|
|
||||||
} elseif ($request->tab == 'pricing') {
|
|
||||||
$rules = [
|
|
||||||
'is_paid' => Rule::in(['0', '1']),
|
|
||||||
'price' => 'required_if:is_paid,1|min:1|nullable|numeric',
|
|
||||||
'discount_flag' => Rule::in(['', '1']),
|
|
||||||
'discounted_price' => 'required_if:discount_flag,1|min:1|nullable|numeric',
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['is_paid'] = $request->is_paid;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['discount_flag'] = $request->discount_flag;
|
|
||||||
$data['discounted_price'] = $request->discounted_price;
|
|
||||||
|
|
||||||
//Course expiry period
|
|
||||||
if ($request->expiry_period == 'limited_time' && is_numeric($request->number_of_month) && $request->number_of_month > 0) {
|
|
||||||
$data['expiry_period'] = $request->number_of_month;
|
|
||||||
} else {
|
|
||||||
$data['expiry_period'] = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
} elseif ($request->tab == 'info') {
|
|
||||||
$rules = [
|
|
||||||
'requirements' => 'array',
|
|
||||||
'outcomes' => 'array',
|
|
||||||
'faqs' => 'array',
|
|
||||||
];
|
|
||||||
|
|
||||||
//Remove empty value by using array filter function
|
|
||||||
$data['requirements'] = json_encode(array_filter($request->requirements, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
$data['outcomes'] = json_encode(array_filter($request->outcomes, fn ($value) => !is_null($value) && $value !== ''));
|
|
||||||
|
|
||||||
$faqs = [];
|
|
||||||
foreach ($request->faq_title as $key => $title) {
|
|
||||||
if ($title != '') {
|
|
||||||
$faqs[] = ['title' => $title, 'description' => $request->faq_description[$key]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$data['faqs'] = json_encode($faqs);
|
|
||||||
} elseif ($request->tab == 'media') {
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/course-thumbnail/" . nice_file_name($request->title, $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
remove_file($query->first()->thumbnail);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->banner) {
|
|
||||||
$data['banner'] = "uploads/course-banner/" . nice_file_name($request->title, $request->banner->extension());
|
|
||||||
FileUploader::upload($request->banner, $data['banner'], 1400, null, 300, 300);
|
|
||||||
remove_file($query->first()->banner);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->preview_video_provider == 'link') {
|
|
||||||
$data['preview'] = $request->preview_link;
|
|
||||||
} elseif ($request->preview_video_provider == 'file' && $request->preview) {
|
|
||||||
$data['preview'] = "uploads/course-preview/" . nice_file_name($request->title, $request->preview->extension());
|
|
||||||
FileUploader::upload($request->preview, $data['preview']);
|
|
||||||
remove_file($query->first()->preview);
|
|
||||||
}
|
|
||||||
} elseif ($request->tab == 'seo') {
|
|
||||||
$course_details = $query->first();
|
|
||||||
$SeoField = SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->first();
|
|
||||||
|
|
||||||
$seo_data['course_id'] = $id;
|
|
||||||
$seo_data['route'] = 'Course Details';
|
|
||||||
$seo_data['name_route'] = 'course.details';
|
|
||||||
$seo_data['meta_title'] = $request->meta_title;
|
|
||||||
$seo_data['meta_description'] = $request->meta_description;
|
|
||||||
$seo_data['meta_robot'] = $request->meta_robot;
|
|
||||||
$seo_data['canonical_url'] = $request->canonical_url;
|
|
||||||
$seo_data['custom_url'] = $request->custom_url;
|
|
||||||
$seo_data['json_ld'] = $request->json_ld;
|
|
||||||
$seo_data['og_title'] = $request->og_title;
|
|
||||||
$seo_data['og_description'] = $request->og_description;
|
|
||||||
$seo_data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$seo_data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
|
|
||||||
$meta_keywords_arr = json_decode($request->meta_keywords, true);
|
|
||||||
$meta_keywords = '';
|
|
||||||
if (is_array($meta_keywords_arr)) {
|
|
||||||
foreach ($meta_keywords_arr as $arr_key => $arr_val) {
|
|
||||||
$meta_keywords .= $meta_keywords == '' ? $arr_val['value'] : ', ' . $arr_val['value'];
|
|
||||||
}
|
|
||||||
$seo_data['meta_keywords'] = $meta_keywords;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if ($request->og_image) {
|
|
||||||
$originalFileName = $course_details->id . '-' . $request->og_image->getClientOriginalName();
|
|
||||||
$destinationPath = 'uploads/seo-og-images/' . $originalFileName;
|
|
||||||
// Move the file to the destination path
|
|
||||||
FileUploader::upload($request->og_image, $destinationPath, 600);
|
|
||||||
$seo_data['og_image'] = $destinationPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($SeoField) {
|
|
||||||
if ($request->og_image) {
|
|
||||||
remove_file($SeoField->og_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
SeoField::where('name_route', 'course.details')->where('course_id', $course_details->id)->update($seo_data);
|
|
||||||
} else {
|
|
||||||
SeoField::insert($seo_data);
|
|
||||||
}
|
|
||||||
} elseif ($request->tab == 'drip-content') {
|
|
||||||
$rules = [
|
|
||||||
'enable_drip_content' => Rule::in(['0', '1']),
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['enable_drip_content'] = $request->enable_drip_content;
|
|
||||||
|
|
||||||
$lesson_completion_role = htmlspecialchars($request->input('lesson_completion_role'));
|
|
||||||
$minimum_duration_input = htmlspecialchars($request->input('minimum_duration'));
|
|
||||||
$minimum_percentage = htmlspecialchars($request->input('minimum_percentage'));
|
|
||||||
$locked_lesson_message = htmlspecialchars($request->input('locked_lesson_message'));
|
|
||||||
|
|
||||||
// Convert time (HH:MM:SS) to seconds
|
|
||||||
$time_parts = explode(':', $minimum_duration_input);
|
|
||||||
$seconds = ($time_parts[0] * 3600) + ($time_parts[1] * 60) + $time_parts[2];
|
|
||||||
|
|
||||||
$drip_data = [
|
|
||||||
'lesson_completion_role' => $lesson_completion_role,
|
|
||||||
'minimum_duration' => $seconds,
|
|
||||||
'minimum_percentage' => $minimum_percentage,
|
|
||||||
'locked_lesson_message' => $locked_lesson_message,
|
|
||||||
];
|
|
||||||
|
|
||||||
$data['drip_content_settings'] = json_encode($drip_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return json_encode(array('validationError' => $validator->getMessageBag()->toArray()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->update($data);
|
|
||||||
|
|
||||||
//For ajax form submission
|
|
||||||
return ['success' => get_phrase('Course updated successfully')];
|
|
||||||
|
|
||||||
//for normal form submission
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$query = Course::where('id', $id);
|
|
||||||
remove_file($query->first()->thumbnail);
|
|
||||||
remove_file($query->first()->banner);
|
|
||||||
remove_file($query->first()->preview);
|
|
||||||
$query->delete();
|
|
||||||
return redirect(route('instructor.courses'))->with('success', get_phrase('Course deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function status($type, $id)
|
|
||||||
{
|
|
||||||
if ($type == 'active') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'active']);
|
|
||||||
} elseif ($type == 'pending') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'pending']);
|
|
||||||
} elseif ($type == 'inactive') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'inactive']);
|
|
||||||
} elseif ($type == 'upcoming') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'upcoming']);
|
|
||||||
} elseif ($type == 'private') {
|
|
||||||
Course::where('id', $id)->update(['status' => 'private']);
|
|
||||||
} else {
|
|
||||||
Course::where('id', $id)->update(['status' => 'draft']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('admin.courses'))->with('success', get_phrase('Course status changed successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function draft($id)
|
|
||||||
{
|
|
||||||
$course = Course::where('id', $id)->first();
|
|
||||||
if (!$course) {
|
|
||||||
$response = [
|
|
||||||
'error' => get_phrase('Data not found.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
$status = $course->status == 'active' ? 'deactivate' : 'active';
|
|
||||||
Course::where('id', $id)->update(['status' => $status]);
|
|
||||||
$response = [
|
|
||||||
'success' => get_phrase('Status has been updated.'),
|
|
||||||
];
|
|
||||||
return json_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function duplicate($id)
|
|
||||||
{
|
|
||||||
$course = Course::where('id', $id);
|
|
||||||
if (auth()->user()->role != 'admin') {
|
|
||||||
$course = $course->where('user_id', auth()->user()->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check course existence
|
|
||||||
if ($course->doesntExist()) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect course and remove unnecessary fields
|
|
||||||
$data = $course->first()->toArray();
|
|
||||||
if (auth()->user()->role == 'admin') {
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
}
|
|
||||||
unset($data['id'], $data['created_at'], $data['updated_at']);
|
|
||||||
$data['status'] = 'pending';
|
|
||||||
|
|
||||||
// insert as new course
|
|
||||||
$course_id = Course::insertGetId($data);
|
|
||||||
Course::where('id', $course_id)->update(['slug' => slugify($data['title']).'-'.$course_id]);
|
|
||||||
|
|
||||||
// go to edit
|
|
||||||
Session::flash('success', get_phrase('Course duplicated.'));
|
|
||||||
return redirect()->route('instructor.course.edit', $course_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,388 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Controllers\WatermarkController;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\File;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
|
|
||||||
|
|
||||||
class LessonController extends Controller
|
|
||||||
{
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$maximum_sort_value = Lesson::where('course_id', $request->course_id)->orderBy('sort', 'desc')->firstOrNew()->sort;
|
|
||||||
// duplicate check
|
|
||||||
if (Lesson::where('course_id', $request->course_id)->where('title', $request->title)->exists()) {
|
|
||||||
Session::flash('error', get_phrase('Lesson already exists.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson = new Lesson();
|
|
||||||
$lesson->title = $request->title;
|
|
||||||
$lesson->user_id = auth()->user()->id;
|
|
||||||
$lesson->course_id = $request->course_id;
|
|
||||||
$lesson->section_id = $request->section_id;
|
|
||||||
$lesson->is_free = $request->free_lesson;
|
|
||||||
$lesson->lesson_type = $request->lesson_type;
|
|
||||||
$lesson->summary = $request->summary;
|
|
||||||
$lesson->sort = $maximum_sort_value + 1;
|
|
||||||
if ($request->lesson_type == 'text') {
|
|
||||||
$lesson->attachment = $request->text_description;
|
|
||||||
$lesson->attachment_type = $request->lesson_provider;
|
|
||||||
} elseif ($request->lesson_type == 'video-url') {
|
|
||||||
|
|
||||||
$lesson->video_type = $request->lesson_provider;
|
|
||||||
$lesson->lesson_src = $request->lesson_src;
|
|
||||||
$lesson->duration = $request->duration;
|
|
||||||
} elseif ($request->lesson_type == 'html5') {
|
|
||||||
|
|
||||||
$lesson->video_type = $request->lesson_provider;
|
|
||||||
$lesson->lesson_src = $request->lesson_src;
|
|
||||||
$lesson->duration = $request->duration;
|
|
||||||
} elseif ($request->lesson_type == 'document_type') {
|
|
||||||
|
|
||||||
if ($request->attachment == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$file = $file_name;
|
|
||||||
}
|
|
||||||
$lesson->attachment = $file;
|
|
||||||
$lesson->attachment_type = $request->attachment_type;
|
|
||||||
} elseif ($request->lesson_type == 'scorm') {
|
|
||||||
if ($request->scorm_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('scorm_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$upload_path = public_path('uploads/lesson_file/scorm_content');
|
|
||||||
|
|
||||||
if (! File::isDirectory($upload_path)) {
|
|
||||||
File::makeDirectory($upload_path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$item->move($upload_path, $file_name);
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
$zip_path = $upload_path . '/' . $file_name;
|
|
||||||
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
|
|
||||||
if ($zip->open($zip_path) === true) {
|
|
||||||
$zip->extractTo($extract_path);
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
File::delete($zip_path);
|
|
||||||
} else {
|
|
||||||
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson['attachment'] = $file;
|
|
||||||
$lesson['attachment_type'] = $request->scorm_provider;
|
|
||||||
} elseif ($request->lesson_type == 'image') {
|
|
||||||
|
|
||||||
if ($request->attachment == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$file = $file_name;
|
|
||||||
}
|
|
||||||
$lesson->attachment = $file;
|
|
||||||
$lesson->attachment_type = $item->getClientOriginalExtension();
|
|
||||||
} elseif ($request->lesson_type == 'vimeo-url') {
|
|
||||||
|
|
||||||
$lesson->video_type = $request->lesson_provider;
|
|
||||||
$lesson->lesson_src = $request->lesson_src;
|
|
||||||
$lesson->duration = $request->duration;
|
|
||||||
} elseif ($request->lesson_type == 'iframe') {
|
|
||||||
|
|
||||||
$lesson->lesson_src = $request->iframe_source;
|
|
||||||
} elseif ($request->lesson_type == 'google_drive') {
|
|
||||||
|
|
||||||
$lesson->video_type = $request->lesson_provider;
|
|
||||||
$lesson->lesson_src = $request->lesson_src;
|
|
||||||
$lesson->duration = $request->duration;
|
|
||||||
} elseif ($request->lesson_type == 'system-video') {
|
|
||||||
|
|
||||||
if ($request->system_video_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('system_video_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/videos');
|
|
||||||
if (! File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = get_player_settings('watermark_type');
|
|
||||||
if ($type == 'ffmpeg') {
|
|
||||||
$watermark = get_player_settings('watermark_logo');
|
|
||||||
if (! $watermark) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! file_exists(public_path($watermark))) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$watermark_status = WatermarkController::encode($item, $file_name, $path);
|
|
||||||
if (! $watermark_status) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$file = FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson->video_type = $request->lesson_provider;
|
|
||||||
$lesson->lesson_src = $file;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson->duration = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson->duration = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson->save();
|
|
||||||
Session::flash('success', get_phrase('Lesson added successfully.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sort(Request $request)
|
|
||||||
{
|
|
||||||
$lessons = json_decode($request->itemJSON);
|
|
||||||
foreach ($lessons as $key => $value) {
|
|
||||||
$updater = $key + 1;
|
|
||||||
Lesson::where('id', $value)->update(['sort' => $updater]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request)
|
|
||||||
{
|
|
||||||
$current_data = Lesson::find($request->id);
|
|
||||||
|
|
||||||
$lesson['title'] = $request->title;
|
|
||||||
$lesson['section_id'] = $request->section_id;
|
|
||||||
$lesson['summary'] = $request->summary;
|
|
||||||
if ($request->lesson_type == 'text') {
|
|
||||||
$lesson['attachment'] = $request->text_description;
|
|
||||||
} elseif ($request->lesson_type == 'video-url') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'html5') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'document_type') {
|
|
||||||
if ($request->attachment) {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$lesson['attachment'] = $file_name;
|
|
||||||
$lesson['attachment_type'] = $request->attachment_type;
|
|
||||||
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'image') {
|
|
||||||
if ($request->attachment) {
|
|
||||||
$item = $request->file('attachment');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/attachment');
|
|
||||||
if (!File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
} else {
|
|
||||||
FileUploader::upload($request->attachment, 'uploads/lesson_file/attachment/' . $file_name);
|
|
||||||
}
|
|
||||||
$lesson['attachment'] = $file_name;
|
|
||||||
$lesson['attachment_type'] = $item->getClientOriginalExtension();
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'vimeo-url') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'iframe') {
|
|
||||||
$lesson['lesson_src'] = $request->iframe_source;
|
|
||||||
} elseif ($request->lesson_type == 'google_drive') {
|
|
||||||
$lesson['lesson_src'] = $request->lesson_src;
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
} elseif ($request->lesson_type == 'scorm') {
|
|
||||||
|
|
||||||
$existing_scorm_folder = $request->attachment;
|
|
||||||
|
|
||||||
if ($request->scorm_file == '') {
|
|
||||||
$file = '';
|
|
||||||
} else {
|
|
||||||
$item = $request->file('scorm_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$upload_path = public_path('uploads/lesson_file/scorm_content');
|
|
||||||
|
|
||||||
if (! File::isDirectory($upload_path)) {
|
|
||||||
File::makeDirectory($upload_path, 0777, true, true);
|
|
||||||
}
|
|
||||||
$this->deleteDir(public_path('uploads/lesson_file/scorm_content/' . $existing_scorm_folder));
|
|
||||||
|
|
||||||
FileUploader::upload($request->scorm_file, 'uploads/lesson_file/scorm_content/' . $file_name);
|
|
||||||
|
|
||||||
$zip = new \ZipArchive();
|
|
||||||
$zip_path = $upload_path . '/' . $file_name;
|
|
||||||
$extract_path = $upload_path . '/' . pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
|
|
||||||
// Remove old SCORM directory if it exists
|
|
||||||
$existing_scorm_path = $upload_path . '/' . $request->scorm_file;
|
|
||||||
if (File::isDirectory($existing_scorm_path)) {
|
|
||||||
File::deleteDirectory($existing_scorm_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($zip->open($zip_path) === true) {
|
|
||||||
$zip->extractTo($extract_path);
|
|
||||||
$zip->close();
|
|
||||||
|
|
||||||
File::delete($zip_path);
|
|
||||||
} else {
|
|
||||||
return response()->json(['error' => 'Failed to extract the SCORM file.'], 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = pathinfo($file_name, PATHINFO_FILENAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
$lesson['attachment'] = $file;
|
|
||||||
$lesson['attachment_type'] = $request->scorm_provider;
|
|
||||||
} elseif ($request->lesson_type == 'system-video') {
|
|
||||||
|
|
||||||
if ($request->system_video_file) {
|
|
||||||
$item = $request->file('system_video_file');
|
|
||||||
$file_name = strtotime('now') . random(4) . '.' . $item->getClientOriginalExtension();
|
|
||||||
|
|
||||||
$path = public_path('uploads/lesson_file/videos');
|
|
||||||
if (! File::isDirectory($path)) {
|
|
||||||
File::makeDirectory($path, 0777, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$type = get_player_settings('watermark_type');
|
|
||||||
if ($type == 'ffmpeg') {
|
|
||||||
$watermark = get_player_settings('watermark_logo');
|
|
||||||
if (! $watermark) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Please configure watermark setting.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! file_exists(public_path($watermark))) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('File doesn\'t exists.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$watermark_status = WatermarkController::encode($item, $file_name, $path);
|
|
||||||
if (! $watermark_status) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('Something went wrong.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileUploader::upload($request->system_video_file, 'uploads/lesson_file/videos/' . $file_name);
|
|
||||||
|
|
||||||
$file = str_replace(public_path('/'), '', $path).'/'. $file_name;
|
|
||||||
$lesson['lesson_src'] = $file;
|
|
||||||
remove_file($current_data->lesson_src);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($request->duration)) {
|
|
||||||
$lesson['duration'] = '00:00:00';
|
|
||||||
} else {
|
|
||||||
$duration_formatter = explode(':', $request->duration);
|
|
||||||
$hour = sprintf('%02d', $duration_formatter[0]);
|
|
||||||
$min = sprintf('%02d', $duration_formatter[1]);
|
|
||||||
$sec = sprintf('%02d', $duration_formatter[2]);
|
|
||||||
$lesson['duration'] = $hour . ':' . $min . ':' . $sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Lesson::where('id', $request->id)->update($lesson);
|
|
||||||
Session::flash('success', get_phrase('lesson update successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteDir($directoryPath)
|
|
||||||
{
|
|
||||||
if (File::exists($directoryPath)) {
|
|
||||||
// Delete all files and subdirectories within the directory
|
|
||||||
File::deleteDirectory($directoryPath);
|
|
||||||
|
|
||||||
// Finally, delete the root directory itself
|
|
||||||
File::delete($directoryPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete($id)
|
|
||||||
{
|
|
||||||
$current_data = Lesson::find($id);
|
|
||||||
remove_file($current_data->lesson_src);
|
|
||||||
remove_file('uploads/lesson_file/attachment/'.$current_data->attachment);
|
|
||||||
|
|
||||||
Lesson::where('id', $id)->delete();
|
|
||||||
Session::flash('success', get_phrase('Delete successfully'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,260 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Live_class;
|
|
||||||
use App\Models\Setting;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class LiveClassController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function live_class_start($id)
|
|
||||||
{
|
|
||||||
$live_class = Live_class::where('id', $id)->first();
|
|
||||||
|
|
||||||
if ($live_class->provider == 'zoom') {
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($live_class->additional_info, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return view('course_player.live_class.zoom_live_class', ['live_class' => $live_class]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_store(Request $request, $course_id)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'class_topic' => 'required|max:255',
|
|
||||||
'class_date_and_time' => 'date|required',
|
|
||||||
'user_id' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['class_topic'] = $request->class_topic;
|
|
||||||
$data['course_id'] = $request->course_id;
|
|
||||||
$data['user_id'] = $request->user_id;
|
|
||||||
$data['provider'] = $request->provider;
|
|
||||||
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$data['note'] = $request->note;
|
|
||||||
|
|
||||||
if ($request->provider == 'zoom') {
|
|
||||||
$meeting_info = $this->create_zoom_live_class($request->class_topic, $request->class_date_and_time);
|
|
||||||
$meeting_info_arr = json_decode($meeting_info, true);
|
|
||||||
if (array_key_exists('code', $meeting_info_arr) && $meeting_info_arr) {
|
|
||||||
return redirect(route('instructor.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('error', get_phrase($meeting_info_arr['message']));
|
|
||||||
}
|
|
||||||
$data['additional_info'] = $meeting_info;
|
|
||||||
}
|
|
||||||
Live_class::insert($data);
|
|
||||||
|
|
||||||
return redirect(route('instructor.course.edit', ['id' => $course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class added successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$previous_meeting_data = Live_class::where('id', $id)->first();
|
|
||||||
|
|
||||||
$request->validate([
|
|
||||||
'class_topic' => 'required|max:255',
|
|
||||||
'class_date_and_time' => 'date|required',
|
|
||||||
'user_id' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['class_topic'] = $request->class_topic;
|
|
||||||
$data['user_id'] = $request->user_id;
|
|
||||||
$data['class_date_and_time'] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$data['note'] = $request->note;
|
|
||||||
|
|
||||||
if ($previous_meeting_data->provider == 'zoom') {
|
|
||||||
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
|
|
||||||
$this->update_zoom_live_class($request->class_topic, $request->class_date_and_time, $previous_meeting_info['id']);
|
|
||||||
$previous_meeting_info["start_time"] = date('Y-m-d\TH:i:s', strtotime($request->class_date_and_time));
|
|
||||||
$previous_meeting_info["topic"] = $request->class_topic;
|
|
||||||
$data['additional_info'] = json_encode($previous_meeting_info);
|
|
||||||
}
|
|
||||||
Live_class::where('id', $id)->update($data);
|
|
||||||
|
|
||||||
return redirect(route('instructor.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class updated successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_delete($id)
|
|
||||||
{
|
|
||||||
$previous_meeting_data = Live_class::where('id', $id)->first();
|
|
||||||
$course = Course::where('id', $previous_meeting_data->course_id)->first();
|
|
||||||
|
|
||||||
if ($course->instructors()->count() > 0) {
|
|
||||||
$previous_meeting_info = json_decode($previous_meeting_data->additional_info, true);
|
|
||||||
$this->delete_zoom_live_class($previous_meeting_info['id']);
|
|
||||||
Live_class::where('id', $id)->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('instructor.course.edit', ['id' => $previous_meeting_data->course_id, 'tab' => 'live-class']))->with('success', get_phrase('Live class deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function live_class_settings()
|
|
||||||
{
|
|
||||||
return view('instructor.setting.live_class_settings');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_live_class_settings(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'zoom_account_email' => 'required:email',
|
|
||||||
'zoom_web_sdk' => 'required|in:active,inactive',
|
|
||||||
'zoom_account_id' => 'required',
|
|
||||||
'zoom_client_id' => 'required',
|
|
||||||
'zoom_client_secret' => 'required',
|
|
||||||
]);
|
|
||||||
|
|
||||||
foreach ($request->all() as $name => $value) {
|
|
||||||
if (Setting::where('type', $name)->count() > 0) {
|
|
||||||
Setting::where('type', $name)->update(['description' => $value]);
|
|
||||||
} else {
|
|
||||||
Setting::insert(['type' => $name, 'description' => $value]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('instructor.live.class.settings'))->with('success', get_phrase('Zoom live class settings has been configured'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_live_class($topic, $date_and_time)
|
|
||||||
{
|
|
||||||
$zoom_account_email = get_settings('zoom_account_email');
|
|
||||||
$token = $this->create_zoom_token();
|
|
||||||
// API Endpoint for creating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
|
|
||||||
|
|
||||||
// Meeting data
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'schedule_for' => $zoom_account_email,
|
|
||||||
'type' => 2, // Scheduled meeting
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
|
|
||||||
'duration' => 60, // Duration in minutes
|
|
||||||
'timezone' => get_settings('timezone'), // Timezone
|
|
||||||
'settings' => [
|
|
||||||
'approval_type' => 2,
|
|
||||||
'join_before_host' => true,
|
|
||||||
'jbh_time' => 0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make POST request to create meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_zoom_live_class($topic, $date_and_time, $meetingId)
|
|
||||||
{
|
|
||||||
$token = $this->create_zoom_token(); // Obtain the access token
|
|
||||||
|
|
||||||
// API Endpoint for updating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Meeting data with updated start time
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // New start time (in UTC)
|
|
||||||
];
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make PATCH request to update meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function delete_zoom_live_class($meetingId)
|
|
||||||
{
|
|
||||||
$token = $this->create_zoom_token(); // Obtain the access token
|
|
||||||
|
|
||||||
// API Endpoint for deleting a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/meetings/' . $meetingId;
|
|
||||||
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make DELETE request to delete meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_token()
|
|
||||||
{
|
|
||||||
// Access the environment variables
|
|
||||||
$clientId = get_settings('zoom_client_id');
|
|
||||||
$clientSecret = get_settings('zoom_client_secret');
|
|
||||||
$accountId = get_settings('zoom_account_id');
|
|
||||||
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
|
|
||||||
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
|
|
||||||
|
|
||||||
$curl = curl_init();
|
|
||||||
|
|
||||||
curl_setopt_array($curl, array(
|
|
||||||
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => '',
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
||||||
CURLOPT_HTTPHEADER => array(
|
|
||||||
'Content-Type: application/x-www-form-urlencoded',
|
|
||||||
'Authorization: ' . $authHeader,
|
|
||||||
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
|
|
||||||
$accessToken = $oauthResponse['access_token'];
|
|
||||||
return $accessToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,507 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\instructor;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\TutorCategory;
|
|
||||||
use App\Models\TutorSubject;
|
|
||||||
use App\Models\TutorBooking;
|
|
||||||
use App\Models\TutorSchedule;
|
|
||||||
use App\Models\TutorCanTeach;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Carbon\Carbon; // Import Carbon class
|
|
||||||
use Carbon\CarbonPeriod; // Import CarbonPeriod for date ranges
|
|
||||||
|
|
||||||
class TutorBookingController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function my_subjects()
|
|
||||||
{
|
|
||||||
// Fetch all records for the instructor
|
|
||||||
$categories = TutorCanTeach::where('instructor_id', auth()->user()->id)
|
|
||||||
->with('category_to_tutorCategory') // Eager load the related category
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Filter out duplicates by category_id
|
|
||||||
$page_data['categories'] = $categories->unique('category_id');
|
|
||||||
return view('instructor.tutor_booking.my_subjects', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function my_subject_add()
|
|
||||||
{}
|
|
||||||
|
|
||||||
public function my_subject_store(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'category_id' => 'required',
|
|
||||||
'subject_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
'price' => 'required'
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['subject_id'] = $request->subject_id;
|
|
||||||
$data['instructor_id'] = auth()->user()->id;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['created_at'] = date('Y-m-d H:i:s');
|
|
||||||
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
$data['thumbnail'] = "uploads/tutor-booking/subject-thumbnail/" . nice_file_name(random(9), $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
TutorCanTeach::insert($data);
|
|
||||||
|
|
||||||
return redirect(route('instructor.my_subjects'))->with('success', get_phrase('Subject added successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function my_subject_edit()
|
|
||||||
{}
|
|
||||||
|
|
||||||
public function my_subject_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'category_id' => 'required',
|
|
||||||
'subject_id' => 'required',
|
|
||||||
'description' => 'required',
|
|
||||||
'price' => 'required'
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Fetch the existing record
|
|
||||||
$subject = TutorCanTeach::findOrFail($id);
|
|
||||||
|
|
||||||
// Prepare the data for update
|
|
||||||
$data['category_id'] = $request->category_id;
|
|
||||||
$data['subject_id'] = $request->subject_id;
|
|
||||||
$data['instructor_id'] = auth()->user()->id;
|
|
||||||
$data['description'] = $request->description;
|
|
||||||
$data['price'] = $request->price;
|
|
||||||
$data['updated_at'] = date('Y-m-d H:i:s');
|
|
||||||
|
|
||||||
// Handle thumbnail upload
|
|
||||||
if ($request->thumbnail) {
|
|
||||||
// Unlink the previous thumbnail if it exists
|
|
||||||
if ($subject->thumbnail && file_exists(public_path($subject->thumbnail))) {
|
|
||||||
unlink(public_path($subject->thumbnail));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a new thumbnail path and upload the new file
|
|
||||||
$data['thumbnail'] = "uploads/tutor-booking/subject-thumbnail/" . nice_file_name(random(9), $request->thumbnail->extension());
|
|
||||||
FileUploader::upload($request->thumbnail, $data['thumbnail'], 400, null, 200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the record
|
|
||||||
TutorCanTeach::where('id', $id)->update($data);
|
|
||||||
|
|
||||||
// Redirect back with success message
|
|
||||||
return redirect(route('instructor.my_subjects'))->with('success', get_phrase('Subject updated successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function my_subject_delete($id)
|
|
||||||
{
|
|
||||||
$query = TutorCanTeach::where('id', $id);
|
|
||||||
$query->delete();
|
|
||||||
|
|
||||||
return redirect(route('instructor.my_subjects'))->with('success', get_phrase('Subject deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function my_subject_category_delete($id)
|
|
||||||
{
|
|
||||||
$subjects = TutorCanTeach::where('category_id', $id)->get();
|
|
||||||
|
|
||||||
if ($subjects->isEmpty()) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('No subjects found for this category'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete all records associated with the category_id
|
|
||||||
TutorCanTeach::where('category_id', $id)->delete();
|
|
||||||
|
|
||||||
// Redirect with a success message
|
|
||||||
return redirect(route('instructor.my_subjects'))->with('success', get_phrase('Subjects for the selected category deleted successfully'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manage_schedules()
|
|
||||||
{
|
|
||||||
// Retrieve the schedules for the authenticated tutor
|
|
||||||
$schedule_list = TutorSchedule::where('tutor_id', auth()->user()->id)->get();
|
|
||||||
|
|
||||||
$schedulesByDate = [];
|
|
||||||
|
|
||||||
foreach ($schedule_list as $schedule) {
|
|
||||||
// Get the formatted date (Y-m-d) from the start time
|
|
||||||
$date = date('Y-m-d', $schedule->start_time);
|
|
||||||
|
|
||||||
// Group schedules by date
|
|
||||||
if (!isset($schedulesByDate[$date])) {
|
|
||||||
$schedulesByDate[$date] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment count for the specific date
|
|
||||||
$schedulesByDate[$date]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$schedules = [];
|
|
||||||
|
|
||||||
foreach ($schedulesByDate as $date => $count) {
|
|
||||||
// Create an info array for each unique date with schedule count
|
|
||||||
$info = [
|
|
||||||
'title' => $count . ' schedules', // Display the count of schedules
|
|
||||||
'start' => $date, // Use the date as start
|
|
||||||
];
|
|
||||||
|
|
||||||
$schedules[] = $info;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the schedules array to JSON
|
|
||||||
$schedules = json_encode($schedules);
|
|
||||||
|
|
||||||
// Pass the schedules to the view
|
|
||||||
return view('instructor.tutor_booking.manage_schedules', ['schedules' => $schedules]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function manage_schedules_by_date($date)
|
|
||||||
{
|
|
||||||
// Parse the provided date to match the expected format (e.g., '12-Feb-24')
|
|
||||||
$parsedDate = \DateTime::createFromFormat('d-M-y', $date);
|
|
||||||
|
|
||||||
if (!$parsedDate) {
|
|
||||||
Session::flash('error', get_phrase('Invalid date format'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$formattedDate = $parsedDate->format('Y-m-d');
|
|
||||||
|
|
||||||
// Get the start and end timestamps for the selected day
|
|
||||||
$dayStart = $parsedDate->setTime(0, 0)->getTimestamp();
|
|
||||||
$dayEnd = $parsedDate->setTime(23, 59, 59)->getTimestamp();
|
|
||||||
|
|
||||||
// Retrieve schedules for the authenticated tutor within the specified day's timestamp range
|
|
||||||
$schedules = TutorSchedule::where('tutor_id', auth()->user()->id)
|
|
||||||
->where('start_time', '>=', $dayStart)
|
|
||||||
->where('start_time', '<=', $dayEnd)
|
|
||||||
->paginate(10);
|
|
||||||
|
|
||||||
|
|
||||||
return view('instructor.tutor_booking.schedules_by_day', ['schedules' => $schedules, 'selected_date' => $date]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function schedule_edit($id = "")
|
|
||||||
{
|
|
||||||
$page_data['schedule_details'] = TutorSchedule::find($id);
|
|
||||||
// Fetch all records for the instructor
|
|
||||||
$categories = TutorCanTeach::where('instructor_id', auth()->user()->id)
|
|
||||||
->with('category_to_tutorCategory') // Eager load the related category
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Filter out duplicates by category_id
|
|
||||||
$page_data['categories'] = $categories->unique('category_id');
|
|
||||||
return view('instructor.tutor_booking.edit_schedule', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function schedule_update(Request $request, $id)
|
|
||||||
{
|
|
||||||
// Validate the form input
|
|
||||||
$validated = $request->validate([
|
|
||||||
'category_id' => 'required|integer',
|
|
||||||
'subject_id' => 'required|integer',
|
|
||||||
'start_time' => 'required|date',
|
|
||||||
'duration' => 'required|integer',
|
|
||||||
'description' => 'nullable|string',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Cast duration to an integer just in case
|
|
||||||
$duration = (int) $validated['duration'];
|
|
||||||
|
|
||||||
// Start time for the session
|
|
||||||
$startDate = Carbon::parse($validated['start_time']);
|
|
||||||
|
|
||||||
// Save single session to TutorSchedule
|
|
||||||
TutorSchedule::where('id', $id)->update([
|
|
||||||
'category_id' => $validated['category_id'],
|
|
||||||
'subject_id' => $validated['subject_id'],
|
|
||||||
'start_time' => $startDate->timestamp, // Store as timestamp
|
|
||||||
'end_time' => $startDate->copy()->addMinutes($duration)->timestamp,
|
|
||||||
'duration' => $duration,
|
|
||||||
'description' => $validated['description'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Extract the date in the desired format (e.g., 12-Feb-24)
|
|
||||||
$date = $startDate->format('d-M-y');
|
|
||||||
|
|
||||||
return redirect()->route('instructor.manage_schedules_by_date', ['date' => $date])->with('success', get_phrase('Schedule updated successfully.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function schedule_delete($id)
|
|
||||||
{
|
|
||||||
// Retrieve the schedule record
|
|
||||||
$schedule = TutorSchedule::find($id);
|
|
||||||
|
|
||||||
if (!$schedule) {
|
|
||||||
return redirect()->back()->with('error', get_phrase('No schedule found for this id'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete the schedule
|
|
||||||
$schedule->delete();
|
|
||||||
|
|
||||||
// Redirect to the route with the formatted date
|
|
||||||
return redirect()->back()->with('success', get_phrase('Schedule deleted successfully.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function add_schedule()
|
|
||||||
{
|
|
||||||
// Fetch all records for the instructor
|
|
||||||
$categories = TutorCanTeach::where('instructor_id', auth()->user()->id)
|
|
||||||
->with('category_to_tutorCategory') // Eager load the related category
|
|
||||||
->get();
|
|
||||||
|
|
||||||
// Filter out duplicates by category_id
|
|
||||||
$page_data['categories'] = $categories->unique('category_id');
|
|
||||||
return view('instructor.tutor_booking.add_schedule', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function schedule_store(Request $request)
|
|
||||||
{
|
|
||||||
// Validate the form input
|
|
||||||
$validated = $request->validate([
|
|
||||||
'category_id' => 'required|integer',
|
|
||||||
'subject_id' => 'required|integer',
|
|
||||||
'tution_type' => 'required|integer', // 1 for single, 0 for repeated
|
|
||||||
'start_time' => 'required|date',
|
|
||||||
'end_time' => 'nullable|date', // Only needed for repeated sessions
|
|
||||||
'duration' => 'required|integer',
|
|
||||||
'description' => 'nullable|string',
|
|
||||||
'1_day' => 'nullable|array', // Only for repeated schedule (array of selected days)
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Cast duration to an integer just in case
|
|
||||||
$duration = (int) $validated['duration'];
|
|
||||||
|
|
||||||
// Start time for the session
|
|
||||||
$startDate = Carbon::parse($validated['start_time']);
|
|
||||||
|
|
||||||
if ($validated['tution_type'] == 0) { // Repeated session (tution_type == 0)
|
|
||||||
if (!empty($validated['end_time'])) {
|
|
||||||
$endDate = Carbon::parse($validated['end_time']);
|
|
||||||
|
|
||||||
// Create a period between start and end dates
|
|
||||||
$period = CarbonPeriod::create($startDate, $endDate);
|
|
||||||
|
|
||||||
// Check if specific days are selected for the repeated schedule
|
|
||||||
if (!empty($validated['1_day'])) {
|
|
||||||
foreach ($period as $date) {
|
|
||||||
$dayOfWeek = strtolower($date->format('l'));
|
|
||||||
if (in_array($dayOfWeek, $validated['1_day'])) {
|
|
||||||
// Save each repeated session to TutorSchedule
|
|
||||||
TutorSchedule::create([
|
|
||||||
'tutor_id' => auth()->user()->id,
|
|
||||||
'category_id' => $validated['category_id'],
|
|
||||||
'subject_id' => $validated['subject_id'],
|
|
||||||
'start_time' => $date->timestamp, // Store as timestamp
|
|
||||||
'end_time' => $date->copy()->addMinutes($duration)->timestamp,
|
|
||||||
'duration' => $duration,
|
|
||||||
'description' => $validated['description'],
|
|
||||||
'tution_type' => $validated['tution_type'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // Single session (tution_type == 1)
|
|
||||||
// Save single session to TutorSchedule
|
|
||||||
TutorSchedule::create([
|
|
||||||
'tutor_id' => auth()->user()->id,
|
|
||||||
'category_id' => $validated['category_id'],
|
|
||||||
'subject_id' => $validated['subject_id'],
|
|
||||||
'start_time' => $startDate->timestamp, // Store as timestamp
|
|
||||||
'end_time' => $startDate->copy()->addMinutes($duration)->timestamp,
|
|
||||||
'duration' => $duration,
|
|
||||||
'description' => $validated['description'],
|
|
||||||
'tution_type' => $validated['tution_type'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect(route('instructor.manage_schedules'))->with('success', get_phrase('Schedule successfully created.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function subject_by_category_id(Request $request)
|
|
||||||
{
|
|
||||||
if (isset($request->category_id)) {
|
|
||||||
$teaches = TutorCanTeach::where('category_id', $request->category_id)->get();
|
|
||||||
return view('instructor.tutor_booking.load_subjects', compact('teaches'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function tutor_booking_list()
|
|
||||||
{
|
|
||||||
// Get the current timestamp for today at midnight
|
|
||||||
$todayStart = strtotime('today');
|
|
||||||
|
|
||||||
// Initialize query for current bookings (today onwards)
|
|
||||||
$currentQuery = TutorBooking::where('tutor_bookings.start_time', '>=', $todayStart)
|
|
||||||
->join('tutor_schedules', 'tutor_bookings.schedule_id', '=', 'tutor_schedules.id')
|
|
||||||
->join('tutor_subjects', 'tutor_schedules.subject_id', '=', 'tutor_subjects.id')
|
|
||||||
->join('users', 'tutor_bookings.student_id', '=', 'users.id')
|
|
||||||
->select('tutor_bookings.*', 'tutor_subjects.name', 'users.name as student_name')
|
|
||||||
->orderBy('tutor_bookings.id', 'desc');
|
|
||||||
|
|
||||||
// Initialize query for archived bookings (before today)
|
|
||||||
$archiveQuery = TutorBooking::where('tutor_bookings.start_time', '<', $todayStart)
|
|
||||||
->join('tutor_schedules', 'tutor_bookings.schedule_id', '=', 'tutor_schedules.id')
|
|
||||||
->join('tutor_subjects', 'tutor_schedules.subject_id', '=', 'tutor_subjects.id')
|
|
||||||
->join('users', 'tutor_bookings.student_id', '=', 'users.id')
|
|
||||||
->select('tutor_bookings.*', 'tutor_subjects.name', 'users.name as student_name')
|
|
||||||
->orderBy('tutor_bookings.id', 'desc');
|
|
||||||
|
|
||||||
// Add search condition for both queries
|
|
||||||
if (request()->has('search')) {
|
|
||||||
$search = request()->query('search');
|
|
||||||
$currentQuery = $currentQuery->where(function ($q) use ($search) {
|
|
||||||
$q->where('users.name', 'LIKE', "%{$search}%")
|
|
||||||
->orWhere('tutor_subjects.name', 'LIKE', "%{$search}%");
|
|
||||||
});
|
|
||||||
|
|
||||||
$archiveQuery = $archiveQuery->where(function ($q) use ($search) {
|
|
||||||
$q->where('users.name', 'LIKE', "%{$search}%")
|
|
||||||
->orWhere('tutor_subjects.name', 'LIKE', "%{$search}%");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paginate results
|
|
||||||
$page_data['booking_list'] = $currentQuery->paginate(20)->appends(request()->query());
|
|
||||||
$page_data['archive_list'] = $archiveQuery->paginate(20, ['*'], 'archive_page')->appends(request()->query());
|
|
||||||
|
|
||||||
// Return the view with the data
|
|
||||||
return view('instructor.tutor_booking.tutor_booking_list', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function join_class($booking_id = "")
|
|
||||||
{
|
|
||||||
$booking_details = TutorBooking::find($booking_id);
|
|
||||||
|
|
||||||
if(empty($booking_details->joining_data)) {
|
|
||||||
$joining_info = $this->create_zoom_meeting($booking_details->booking_to_schedule->schedule_to_tutorSubjects->name, $booking_details->start_time);
|
|
||||||
|
|
||||||
$meeting_info = json_decode($joining_info, true);
|
|
||||||
|
|
||||||
if (array_key_exists('code', $meeting_info) && $meeting_info) {
|
|
||||||
return redirect()->back()->with('error', get_phrase($meeting_info['message']));
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['joining_data'] = $joining_info;
|
|
||||||
|
|
||||||
TutorBooking::where('id', $booking_id)->update($data);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($booking_details->joining_data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
$current_time = time();
|
|
||||||
$extended_time = $current_time + (60 * 15);
|
|
||||||
|
|
||||||
$booking = TutorBooking::where('id', $booking_id)
|
|
||||||
->where('start_time', '<', $extended_time)
|
|
||||||
->where('end_time', '>', $current_time)
|
|
||||||
->where('tutor_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $booking) {
|
|
||||||
Session::flash('error', get_phrase('Session not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
$page_data['booking'] = $booking;
|
|
||||||
$page_data['user'] = get_user_info($booking->tutor_id);
|
|
||||||
$page_data['is_host'] = 1;
|
|
||||||
return view('instructor.tutor_booking.join_tution', $page_data);
|
|
||||||
} else {
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_meeting($topic, $date_and_time)
|
|
||||||
{
|
|
||||||
$zoom_account_email = get_settings('zoom_account_email');
|
|
||||||
$token = $this->create_zoom_token();
|
|
||||||
// API Endpoint for creating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
|
|
||||||
|
|
||||||
// Meeting data
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'schedule_for' => $zoom_account_email,
|
|
||||||
'type' => 2, // Scheduled meeting
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
|
|
||||||
'duration' => 60, // Duration in minutes
|
|
||||||
'timezone' => get_settings('timezone'), // Timezone
|
|
||||||
'settings' => [
|
|
||||||
'approval_type' => 2,
|
|
||||||
'join_before_host' => true,
|
|
||||||
'jbh_time' => 0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make POST request to create meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_token()
|
|
||||||
{
|
|
||||||
// Access the environment variables
|
|
||||||
$clientId = get_settings('zoom_client_id');
|
|
||||||
$clientSecret = get_settings('zoom_client_secret');
|
|
||||||
$accountId = get_settings('zoom_account_id');
|
|
||||||
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
|
|
||||||
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
|
|
||||||
|
|
||||||
$curl = curl_init();
|
|
||||||
|
|
||||||
curl_setopt_array($curl, array(
|
|
||||||
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => '',
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
||||||
CURLOPT_HTTPHEADER => array(
|
|
||||||
'Content-Type: application/x-www-form-urlencoded',
|
|
||||||
'Authorization: ' . $authHeader,
|
|
||||||
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
|
|
||||||
$accessToken = $oauthResponse['access_token'];
|
|
||||||
return $accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,147 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\student;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\BootcampLiveClass;
|
|
||||||
use App\Models\BootcampPurchase;
|
|
||||||
use App\Models\BootcampResource;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class MyBootcampsController extends Controller
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
date_default_timezone_set('Asia/Dhaka');
|
|
||||||
}
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$page_data['my_bootcamps'] = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_purchases.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_purchases.status', 1)
|
|
||||||
->select('bootcamps.*')->latest('id')->paginate(10)->appends(request()->query());
|
|
||||||
return view(theme_path() . 'student.my_bootcamps.index', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show($slug)
|
|
||||||
{
|
|
||||||
$page_data['bootcamp'] = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_purchases.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_purchases.status', 1)
|
|
||||||
->where('bootcamps.slug', $slug)
|
|
||||||
->select('bootcamps.*')->latest('id')->first();
|
|
||||||
|
|
||||||
if (! $page_data['bootcamp']) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
return view(theme_path() . 'student.my_bootcamps.details', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function invoice($id)
|
|
||||||
{
|
|
||||||
$invoice = BootcampPurchase::join('bootcamps', 'bootcamp_purchases.bootcamp_id', 'bootcamps.id')
|
|
||||||
->where('bootcamp_purchases.id', $id)
|
|
||||||
->select(
|
|
||||||
'bootcamp_purchases.*',
|
|
||||||
'bootcamps.title',
|
|
||||||
'bootcamps.slug',
|
|
||||||
)->first();
|
|
||||||
|
|
||||||
if (! $invoice) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$page_data['invoice'] = $invoice;
|
|
||||||
return view(theme_path() . 'student.my_bootcamps.invoice', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function join_class($slug)
|
|
||||||
{
|
|
||||||
$current_time = time();
|
|
||||||
$extended_time = $current_time + (60 * 15);
|
|
||||||
|
|
||||||
$class = BootcampLiveClass::join('bootcamp_modules', 'bootcamp_live_classes.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->join('bootcamp_purchases', function ($join) {
|
|
||||||
$join->on('bootcamps.id', 'bootcamp_purchases.bootcamp_id')
|
|
||||||
->where('bootcamp_purchases.user_id', auth()->user()->id)
|
|
||||||
->where('bootcamp_purchases.status', 1);
|
|
||||||
})
|
|
||||||
->where('bootcamp_live_classes.slug', $slug)
|
|
||||||
->select('bootcamp_live_classes.*', 'bootcamps.id as bootcamp_id', 'bootcamp_purchases.user_id as enrolled_user')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Class not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($current_time > $class->end_time) {
|
|
||||||
Session::flash('error', get_phrase('Time up! Class is over.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
$page_data['class'] = $class;
|
|
||||||
$page_data['user'] = get_user_info($class->enrolled_user);
|
|
||||||
$page_data['is_host'] = 0;
|
|
||||||
return view('bootcamp_online_class.index', $page_data);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($class->joining_data, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function download($id)
|
|
||||||
{
|
|
||||||
$resource = BootcampResource::join('bootcamp_modules', 'bootcamp_resources.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->join('bootcamp_purchases', 'bootcamps.id', 'bootcamp_purchases.bootcamp_id')
|
|
||||||
->where('bootcamp_resources.id', $id)
|
|
||||||
->where('bootcamp_resources.upload_type', 'resource')
|
|
||||||
->where('bootcamp_purchases.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_resources.*', 'bootcamp_purchases.user_id')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $resource) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$file_path = public_path($resource->file);
|
|
||||||
if (! file_exists($file_path)) {
|
|
||||||
Session::flash('error', get_phrase('File does not exist.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
return response()->download($file_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function play($file)
|
|
||||||
{
|
|
||||||
$class = BootcampResource::join('bootcamp_modules', 'bootcamp_resources.module_id', 'bootcamp_modules.id')
|
|
||||||
->join('bootcamps', 'bootcamp_modules.bootcamp_id', 'bootcamps.id')
|
|
||||||
->join('bootcamp_purchases', 'bootcamps.id', 'bootcamp_purchases.bootcamp_id')
|
|
||||||
->where('bootcamp_resources.title', $file)
|
|
||||||
->where('bootcamp_resources.upload_type', 'record')
|
|
||||||
->where('bootcamp_purchases.user_id', auth()->user()->id)
|
|
||||||
->select('bootcamp_resources.*', 'bootcamp_purchases.user_id as enrolled_user', 'bootcamps.slug as bootcamp_slug')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (! $class) {
|
|
||||||
Session::flash('error', get_phrase('Data not found.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$file_path = public_path($class->file);
|
|
||||||
if (! file_exists($file_path)) {
|
|
||||||
Session::flash('error', get_phrase('File does not exist.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('class_record.player', compact('class'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\student;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
|
|
||||||
class MyProfileController extends Controller
|
|
||||||
{
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$page_data['user_details'] = User::find(auth()->user()->id);
|
|
||||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.my_profile.index';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, $user_id)
|
|
||||||
{
|
|
||||||
$rules = [
|
|
||||||
'name' => 'required',
|
|
||||||
'email' => 'required|email|unique:users,email,' . $user_id,
|
|
||||||
];
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['name'] = $request->name;
|
|
||||||
$data['email'] = $request->email;
|
|
||||||
$data['phone'] = $request->phone;
|
|
||||||
$data['website'] = $request->website;
|
|
||||||
$data['facebook'] = $request->facebook;
|
|
||||||
$data['twitter'] = $request->twitter;
|
|
||||||
$data['linkedin'] = $request->linkedin;
|
|
||||||
$data['skills'] = $request->skills;
|
|
||||||
$data['biography'] = $request->biography;
|
|
||||||
|
|
||||||
User::where('id', $user_id)->update($data);
|
|
||||||
Session::flash('success', get_phrase('Profile updated successfully.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update_profile_picture(Request $request)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'photo' => 'required|image|mimes:jpeg,png,jpg,webp,tiff|max:3072',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// process file
|
|
||||||
$file = $request->photo;
|
|
||||||
$file_name = Str::random(20) . '.' . $file->extension();
|
|
||||||
$path = 'uploads/users/' . auth()->user()->role . '/' . $file_name;
|
|
||||||
FileUploader::upload($file, $path, null, null, 300);
|
|
||||||
|
|
||||||
User::where('id', auth()->user()->id)->update(['photo' => $path]);
|
|
||||||
Session::flash('success', get_phrase('Profile picture updated.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function changePassword(Request $request)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'current_password' => 'required',
|
|
||||||
'new_password' => 'required|min:4',
|
|
||||||
'confirm_password' => 'required|same:new_password',
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Check if the current password is correct
|
|
||||||
if (!Auth::attempt(['email' => auth()->user()->email, 'password' => $request->current_password])) {
|
|
||||||
Session::flash('error', 'Current password is incorrect.');
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update password
|
|
||||||
auth()->user()->update(['password' => Hash::make($request->new_password)]);
|
|
||||||
|
|
||||||
Session::flash('success', 'Password changed successfully.');
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\student;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\CartItem;
|
|
||||||
use App\Models\FileUploader;
|
|
||||||
use App\Models\OfflinePayment;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class OfflinePaymentController extends Controller
|
|
||||||
{
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
// check amount
|
|
||||||
$payment_details = Session::get('payment_details');
|
|
||||||
$item_id_arr = [];
|
|
||||||
foreach($payment_details['items'] as $item){
|
|
||||||
$item_id_arr[] = $item['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$rules = [
|
|
||||||
'doc' => 'required|mimes:jpeg,jpg,pdf,txt,png,docx,doc|max:3072',
|
|
||||||
];
|
|
||||||
$validator = Validator::make($request->all(), $rules);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return redirect()->back()->withErrors($validator)->withInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$file = $request->doc;
|
|
||||||
$file_name = Str::random(20) . '.' . $file->extension();
|
|
||||||
$path = 'uploads/offline_payment/' . slugify(auth()->user()->name) . '/' . $file_name;
|
|
||||||
FileUploader::upload($file, $path, null, null, 300);
|
|
||||||
|
|
||||||
$offline_payment['user_id'] = auth()->user()->id;
|
|
||||||
$offline_payment['item_type'] = $request->item_type;
|
|
||||||
$offline_payment['items'] = json_encode($item_id_arr);
|
|
||||||
$offline_payment['tax'] = $payment_details['tax'];
|
|
||||||
$offline_payment['total_amount'] = $payment_details['payable_amount'];
|
|
||||||
$offline_payment['doc'] = $path;
|
|
||||||
$offline_payment['coupon'] = $payment_details['coupon'] ?? null;
|
|
||||||
|
|
||||||
// insert offline payment history
|
|
||||||
OfflinePayment::insert($offline_payment);
|
|
||||||
|
|
||||||
// remove from cart
|
|
||||||
if ($request->item_type == 'course') {
|
|
||||||
$url = 'purchase.history';
|
|
||||||
CartItem::whereIn('course_id', $item_id_arr)->where('user_id', auth()->user()->id)->delete();
|
|
||||||
} elseif ($request->item_type == 'bootcamp') {
|
|
||||||
$url = 'bootcamps';
|
|
||||||
} elseif ($request->item_type == 'package') {
|
|
||||||
$url = 'team.packages';
|
|
||||||
} elseif ($request->item_type == 'tutor_booking') {
|
|
||||||
$url = 'tutor_list';
|
|
||||||
}
|
|
||||||
|
|
||||||
// return to courses
|
|
||||||
Session::flash('success', get_phrase('The payment will be completed once the admin reviews and approves it.'));
|
|
||||||
return redirect()->route($url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\student;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\Course;
|
|
||||||
use App\Models\Lesson;
|
|
||||||
use App\Models\Question;
|
|
||||||
use App\Models\QuizSubmission;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class QuizController extends Controller
|
|
||||||
{
|
|
||||||
public function quiz_submit(Request $request)
|
|
||||||
{
|
|
||||||
$retake = Lesson::where('id', $request->quiz_id)->value('retake');
|
|
||||||
$submit = QuizSubmission::where('quiz_id', $request->quiz_id)->where('user_id', auth()->user()->id)->count();
|
|
||||||
if ($submit > $retake) {
|
|
||||||
Session::flash('warning', get_phrase('Attempt has been over.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
$inputs = collect($request->all());
|
|
||||||
$quiz_id = $inputs->pull('quiz_id');
|
|
||||||
$inputs->forget(['_token', 'quiz_id']);
|
|
||||||
|
|
||||||
$submits = $inputs->whereNotNull();
|
|
||||||
foreach ($submits as $key => $submit) {
|
|
||||||
if (is_string($submit) && ($submit != 'true' && $submit != 'false')) {
|
|
||||||
$submits[$key] = array_column(json_decode($submit), 'value');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$question_ids = $submits->keys();
|
|
||||||
$submitted_answers = $submits->values();
|
|
||||||
$questions = Question::whereIn('id', $question_ids)->get();
|
|
||||||
|
|
||||||
$right_answers = $wrong_answers = [];
|
|
||||||
foreach ($questions as $key => $question) {
|
|
||||||
|
|
||||||
$correct_answer = json_decode($question->answer, true);
|
|
||||||
$submitted = $submitted_answers[$key];
|
|
||||||
|
|
||||||
if ($question->type == 'mcq') {
|
|
||||||
$isCorrect = empty(array_diff($correct_answer, $submitted)) && empty(array_diff($submitted, $correct_answer));
|
|
||||||
} elseif ($question->type == 'fill_blanks') {
|
|
||||||
$isCorrect = count($correct_answer) === count($submitted);
|
|
||||||
|
|
||||||
if ($isCorrect) {
|
|
||||||
for ($i = 0; $i < count($correct_answer); $i++) {
|
|
||||||
if (strtolower($correct_answer[$i]) != strtolower($submitted[$i])) {
|
|
||||||
$isCorrect = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$isCorrect = false;
|
|
||||||
}
|
|
||||||
} elseif ($question->type == 'true_false') {
|
|
||||||
$isCorrect = strtolower(json_encode($correct_answer)) == strtolower($submitted);
|
|
||||||
}
|
|
||||||
|
|
||||||
$isCorrect ? $right_answers[] = $question->id : $wrong_answers[] = $question->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['quiz_id'] = $quiz_id;
|
|
||||||
$data['user_id'] = auth()->user()->id;
|
|
||||||
$data['correct_answer'] = $right_answers ? json_encode($right_answers) : null;
|
|
||||||
$data['wrong_answer'] = $wrong_answers ? json_encode($wrong_answers) : null;
|
|
||||||
$data['submits'] = $submits->count() > 0 ? json_encode($submits->toArray()) : null;
|
|
||||||
|
|
||||||
QuizSubmission::insert($data);
|
|
||||||
Session::flash('success', get_phrase('Your answers have been submitted.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function load_result(Request $request)
|
|
||||||
{
|
|
||||||
$page_data['quiz'] = Lesson::where('id', $request->quiz_id)->first();
|
|
||||||
$page_data['questions'] = Question::where('quiz_id', $request->quiz_id)->get();
|
|
||||||
$page_data['result'] = QuizSubmission::where('id', $request->submit_id)
|
|
||||||
->where('quiz_id', $request->quiz_id)
|
|
||||||
->where('user_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
return view('course_player.quiz.result', $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function load_questions(Request $request)
|
|
||||||
{
|
|
||||||
$page_data['quiz'] = Lesson::where('id', $request->quiz_id)->first();
|
|
||||||
$page_data['questions'] = Question::where('quiz_id', $request->quiz_id)->get();
|
|
||||||
$page_data['submits'] = QuizSubmission::where('quiz_id', $request->quiz_id)
|
|
||||||
->where('user_id', auth()->user()->id)
|
|
||||||
->get();
|
|
||||||
$page_data['course_details'] = Course::where('id', $page_data['quiz']->course_id)->first();
|
|
||||||
return view('course_player.quiz.questions', $page_data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,264 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\student;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\TutorBooking;
|
|
||||||
use App\Models\TutorSchedule;
|
|
||||||
use App\Models\TutorReview;
|
|
||||||
use App\Models\OfflinePayment;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class TutorBookingController extends Controller
|
|
||||||
{
|
|
||||||
public function my_bookings()
|
|
||||||
{
|
|
||||||
// Get the current timestamp for today at midnight
|
|
||||||
$todayStart = strtotime('today');
|
|
||||||
$todayEnd = strtotime('tomorrow') - 1;
|
|
||||||
|
|
||||||
// Retrieve tutors with schedules starting within today
|
|
||||||
$page_data['my_bookings'] = TutorBooking::where('student_id', auth()->user()->id)->where('start_time', '>=', $todayStart)->orderBy('id', 'desc')->paginate(10);
|
|
||||||
|
|
||||||
$page_data['my_archive_bookings'] = TutorBooking::where('student_id', auth()->user()->id)->where('start_time', '<', $todayStart)->orderBy('id', 'desc')->paginate(10);
|
|
||||||
|
|
||||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.my_bookings.index';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function booking_invoice($id = "")
|
|
||||||
{
|
|
||||||
$page_data['booking'] = TutorBooking::find($id);
|
|
||||||
$page_data['invoice'] = random(10);
|
|
||||||
|
|
||||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.my_bookings.invoice';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//paymnet
|
|
||||||
public function purchase($id)
|
|
||||||
{
|
|
||||||
$schedule = TutorSchedule::find($id);
|
|
||||||
|
|
||||||
// check schedule owner
|
|
||||||
if ($schedule->tutor_id == auth()->user()->id) {
|
|
||||||
Session::flash('error', get_phrase('You own this schedule.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check schedule is booked or not
|
|
||||||
if (TutorBooking::where('student_id', auth()->user()->id)->where('schedule_id', $id)->exists()) {
|
|
||||||
Session::flash('error', get_phrase('Schedule is already booked.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check any offline processing data
|
|
||||||
$processing_payments = OfflinePayment::where([
|
|
||||||
'user_id' => auth()->user()->id,
|
|
||||||
'items' => $schedule->id,
|
|
||||||
'item_type' => 'tutor_booking',
|
|
||||||
'status' => 0,
|
|
||||||
])
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($processing_payments) {
|
|
||||||
Session::flash('warning', get_phrase('Your request is in process.'));
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare team package payment data
|
|
||||||
$payment_details = [
|
|
||||||
'items' => [
|
|
||||||
[
|
|
||||||
'id' => $schedule->id,
|
|
||||||
'title' => $schedule->schedule_to_tutorCategory->name,
|
|
||||||
'subtitle' => $schedule->schedule_to_tutorSubjects->name,
|
|
||||||
'price' => $schedule->schedule_to_tutorCanTeach->price,
|
|
||||||
'discount_price' => '',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
|
|
||||||
'custom_field' => [
|
|
||||||
'item_type' => 'tutor_booking',
|
|
||||||
'pay_for' => get_phrase('Tutor Schedule Booking'),
|
|
||||||
],
|
|
||||||
|
|
||||||
'success_method' => [
|
|
||||||
'model_name' => 'TutorBooking',
|
|
||||||
'function_name' => 'purchase_schedule',
|
|
||||||
],
|
|
||||||
|
|
||||||
'payable_amount' => round($schedule->schedule_to_tutorCanTeach->price, 2),
|
|
||||||
'tax' => 0,
|
|
||||||
'cancel_url' => route('tutor_schedule', [$schedule->tutor_id, slugify($schedule->schedule_to_tutor->name)]),
|
|
||||||
'success_url' => route('payment.success', ''),
|
|
||||||
];
|
|
||||||
|
|
||||||
Session::put(['payment_details' => $payment_details]);
|
|
||||||
return redirect()->route('payment');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function join_class($booking_id = "")
|
|
||||||
{
|
|
||||||
$current_time = time();
|
|
||||||
$extended_time = $current_time + (60 * 15);
|
|
||||||
|
|
||||||
$booking = TutorBooking::where('id', $booking_id)
|
|
||||||
->where('start_time', '<', $extended_time)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (!empty($booking) && $current_time > $booking->end_time) {
|
|
||||||
Session::flash('error', get_phrase('Time up! Session is over.'));
|
|
||||||
return redirect()->route('my_bookings', ['tab' => 'live-upcoming']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! $booking) {
|
|
||||||
Session::flash('error', get_phrase('You can join the class 15 minutes before the class start or Session not found.'));
|
|
||||||
return redirect()->route('my_bookings', ['tab' => 'live-upcoming']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(empty($booking->joining_data)) {
|
|
||||||
$joining_info = $this->create_zoom_meeting($booking->booking_to_schedule->schedule_to_tutorSubjects->name, $booking->start_time);
|
|
||||||
|
|
||||||
$meeting_info = json_decode($joining_info, true);
|
|
||||||
|
|
||||||
if (array_key_exists('code', $meeting_info) && $meeting_info) {
|
|
||||||
return redirect()->back()->with('error', get_phrase($meeting_info['message']));
|
|
||||||
}
|
|
||||||
|
|
||||||
$data['joining_data'] = $joining_info;
|
|
||||||
|
|
||||||
TutorBooking::where('id', $booking_id)->update($data);
|
|
||||||
|
|
||||||
$booking->joining_data = $joining_info;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_settings('zoom_web_sdk') == 'active') {
|
|
||||||
$page_data['booking'] = $booking;
|
|
||||||
$page_data['user'] = get_user_info($booking->student_id);
|
|
||||||
$page_data['is_host'] = 0;
|
|
||||||
|
|
||||||
$view_path = 'frontend.' . get_frontend_settings('theme') . '.student.my_bookings.join_tution';
|
|
||||||
return view($view_path, $page_data);
|
|
||||||
} else {
|
|
||||||
$meeting_info = json_decode($booking->joining_data, true);
|
|
||||||
return redirect($meeting_info['start_url']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_meeting($topic, $date_and_time)
|
|
||||||
{
|
|
||||||
$zoom_account_email = get_settings('zoom_account_email');
|
|
||||||
$token = $this->create_zoom_token();
|
|
||||||
// API Endpoint for creating a meeting
|
|
||||||
$zoomEndpoint = 'https://api.zoom.us/v2/users/me/meetings';
|
|
||||||
|
|
||||||
// Meeting data
|
|
||||||
$meetingData = [
|
|
||||||
'topic' => $topic,
|
|
||||||
'schedule_for' => $zoom_account_email,
|
|
||||||
'type' => 2, // Scheduled meeting
|
|
||||||
'start_time' => date('Y-m-d\TH:i:s', strtotime($date_and_time)), // Start time (in UTC)
|
|
||||||
'duration' => 60, // Duration in minutes
|
|
||||||
'timezone' => get_settings('timezone'), // Timezone
|
|
||||||
'settings' => [
|
|
||||||
'approval_type' => 2,
|
|
||||||
'join_before_host' => true,
|
|
||||||
'jbh_time' => 0,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
// Prepare headers
|
|
||||||
$headers = [
|
|
||||||
'Authorization: Bearer ' . $token,
|
|
||||||
'Content-Type: application/json',
|
|
||||||
];
|
|
||||||
|
|
||||||
// Make POST request to create meeting
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zoomEndpoint);
|
|
||||||
curl_setopt($ch, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($meetingData));
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
// JSON response
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function create_zoom_token()
|
|
||||||
{
|
|
||||||
// Access the environment variables
|
|
||||||
$clientId = get_settings('zoom_client_id');
|
|
||||||
$clientSecret = get_settings('zoom_client_secret');
|
|
||||||
$accountId = get_settings('zoom_account_id');
|
|
||||||
$oauthUrl = 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId; // Replace with your OAuth endpoint URL
|
|
||||||
$authHeader = 'Basic ' . base64_encode($clientId . ':' . $clientSecret);
|
|
||||||
|
|
||||||
$curl = curl_init();
|
|
||||||
|
|
||||||
curl_setopt_array($curl, array(
|
|
||||||
CURLOPT_URL => 'https://zoom.us/oauth/token?grant_type=account_credentials&account_id=' . $accountId,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => '',
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
||||||
CURLOPT_HTTPHEADER => array(
|
|
||||||
'Content-Type: application/x-www-form-urlencoded',
|
|
||||||
'Authorization: ' . $authHeader,
|
|
||||||
'Cookie: __cf_bm=kn5ec2sntPlDgQWVWtSYdPeISb6bp6F7NHwuAFJQaGk-1736318967-1.0.1.1-SeM4z5pIb.nrMno35jg3y5BdXib.GPP13s2_yNnqz6LxbU9zsFTfZQc3a_Di94qx3DoyQjBT2Osz7idFMWWOrw; _zm_chtaid=816; _zm_ctaid=nbT15WlMTsCEAgCyUg3rYw.1736318967206.63747957ef3128f771210fb69e8d6831; _zm_mtk_guid=fa77ae1ac8e349bea690b72d942d6de6; _zm_page_auth=us04_c_uqPDVOshQQK6FRkhQPiPRA; _zm_ssid=us04_c_atJ4QboaQZG4Lw4U-Wpx6A; cred=A404810ADF33AFC21FF517216A4CB862'
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
$oauthResponse = json_decode($response, true) ?? ['access_token' => ''];
|
|
||||||
$accessToken = $oauthResponse['access_token'];
|
|
||||||
return $accessToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function tutor_review(Request $request)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
'rating' => 'required|integer|min:1|max:5',
|
|
||||||
'review' => 'nullable|string|max:1000',
|
|
||||||
'tutor_id' => 'required|integer|exists:users,id',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$studentId = Auth::id();
|
|
||||||
$tutorId = $request->input('tutor_id');
|
|
||||||
|
|
||||||
// Check if a review already exists
|
|
||||||
$existingReview = TutorReview::where('tutor_id', $tutorId)
|
|
||||||
->where('student_id', $studentId)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($existingReview) {
|
|
||||||
// Update the existing review
|
|
||||||
$existingReview->update([
|
|
||||||
'rating' => $request->input('rating'),
|
|
||||||
'review' => $request->input('review'),
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
// Create a new review
|
|
||||||
TutorReview::create([
|
|
||||||
'tutor_id' => $tutorId,
|
|
||||||
'student_id' => $studentId,
|
|
||||||
'rating' => $request->input('rating'),
|
|
||||||
'review' => $request->input('review'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back()->with('success', 'Review submitted successfully.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Middleware;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
|
||||||
|
|
||||||
class VerifyCsrfToken extends Middleware
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The URIs that should be excluded from CSRF verification.
|
|
||||||
*
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $except = [
|
|
||||||
'login', 'admin/section/sort', 'admin/lesson/sort', 'wishlist/add', 'course/enroll', 'cart/add', 'cart/delete', 'buy/course', 'Invoice', 'message/new/store', 'admin/permissions', 'admin/permissions/store', 'instructor/section/sort', 'instructor/lesson/sort', 'payment/success/*', '/payment-notification/doku', 'payment-notification/doku',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class Knowledge_base extends Model
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class Knowledge_base_topick extends Model
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class Setting extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected $fillable = ['type', 'description'];
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace App\Models\payment_gateway;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class Aamarpay extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public static function payment_status($identifier, $transaction_keys = [])
|
|
||||||
{
|
|
||||||
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
|
|
||||||
if (is_array($_POST) && $_POST['pay_status'] == "Successful") {
|
|
||||||
$transaction_keys = $_POST['mer_txnid'];
|
|
||||||
$store_id = $keys['store_id'];
|
|
||||||
$signature_key = $keys['signature_key'];
|
|
||||||
|
|
||||||
if ($payment_gateway->test_mode == 1) {
|
|
||||||
$url = "https://sandbox.aamarpay.com/api/v1/trxcheck/request.php?request_id=$transaction_keys&store_id=$store_id&signature_key=$signature_key&type=json"; //sandbox
|
|
||||||
} else {
|
|
||||||
$url = "https://secure.aamarpay.com/api/v1/trxcheck/request.php?request_id=$transaction_keys&store_id=$store_id&signature_key=$signature_key&type=json"; //live url
|
|
||||||
}
|
|
||||||
|
|
||||||
$curl_handle = curl_init();
|
|
||||||
curl_setopt($curl_handle, CURLOPT_URL, $url);
|
|
||||||
curl_setopt($curl_handle, CURLOPT_VERBOSE, true);
|
|
||||||
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
$buffer = curl_exec($curl_handle);
|
|
||||||
curl_close($curl_handle);
|
|
||||||
$arr = json_decode($buffer, true);
|
|
||||||
|
|
||||||
if (is_array($arr) && $arr['pay_status'] == "Successful") {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function payment_create($identifier)
|
|
||||||
{
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$user = DB::table('users')->where('id', auth()->user()->id)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
|
|
||||||
$products_name = '';
|
|
||||||
foreach ($payment_details['items'] as $key => $value):
|
|
||||||
if ($key == 0) {
|
|
||||||
$products_name .= $value['title'];
|
|
||||||
} else {
|
|
||||||
$products_name .= ', ' . $value['title'];
|
|
||||||
}
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
if ($payment_gateway->test_mode == 1):
|
|
||||||
$store_id = $keys['store_id'];
|
|
||||||
$signature_key = $keys['signature_key'];
|
|
||||||
$payment_url = 'https://sandbox.aamarpay.com/index.php';
|
|
||||||
else:
|
|
||||||
$store_id = $keys['signature_key'];
|
|
||||||
$signature_key = $keys['signature_live_key'];
|
|
||||||
$payment_url = 'https://secure.aamarpay.com/index.php';
|
|
||||||
endif;
|
|
||||||
|
|
||||||
$curl = curl_init();
|
|
||||||
|
|
||||||
curl_setopt_array($curl, array(
|
|
||||||
CURLOPT_URL => $payment_url,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => '',
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
||||||
CURLOPT_POSTFIELDS => array('store_id' => $store_id,
|
|
||||||
'signature_key' => $signature_key,
|
|
||||||
'cus_name' => $user->name,
|
|
||||||
'cus_email' => $user->email,
|
|
||||||
'cus_city' => $user->address,
|
|
||||||
'cus_phone' => $user->phone,
|
|
||||||
'amount' => round($payment_details['payable_amount']),
|
|
||||||
'currency' => $payment_gateway->currency,
|
|
||||||
'tran_id' => "AAMAR_TXN_" . uniqid(),
|
|
||||||
'desc' => $identifier,
|
|
||||||
'success_url' => $payment_details['success_url'] . '/' . $payment_gateway->identifier,
|
|
||||||
'fail_url' => $payment_details['cancel_url'],
|
|
||||||
'cancel_url' => $payment_details['cancel_url'],
|
|
||||||
'type' => 'json'),
|
|
||||||
));
|
|
||||||
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
curl_close($curl);
|
|
||||||
|
|
||||||
$responseObj = json_decode($response);
|
|
||||||
|
|
||||||
if (isset($responseObj->payment_url) && ! empty($responseObj->payment_url)) {
|
|
||||||
$paymentUrl = $responseObj->payment_url;
|
|
||||||
|
|
||||||
return $paymentUrl;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,114 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models\payment_gateway;
|
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use DB;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class Doku extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public static function payment_status($identifier, $bodyData = [], $headerData = [])
|
|
||||||
{
|
|
||||||
|
|
||||||
// print_r($bodyData);
|
|
||||||
// print_r($headerData);
|
|
||||||
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
$test_mode = $payment_gateway->test_mode == 1 ? 1 : 0;
|
|
||||||
|
|
||||||
if ($test_mode == 1) {
|
|
||||||
$key = $keys['public_test_key'];
|
|
||||||
$secret_key = $keys['secret_test_key'];
|
|
||||||
} else {
|
|
||||||
$key = $keys['public_live_key'];
|
|
||||||
$secret_key = $keys['secret_live_key'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// print_r($bodyData);
|
|
||||||
|
|
||||||
if (count($bodyData) > 0) {
|
|
||||||
// $notificationHeader = $headerData;
|
|
||||||
// $notificationBody = json_encode($bodyData);
|
|
||||||
// $notificationPath = '/payment-notification/doku';
|
|
||||||
// // Adjust according to your notification path
|
|
||||||
// $secretKey = $secret_key; // Adjust according to your secret key
|
|
||||||
|
|
||||||
// $digest = base64_encode(hash('sha256', $notificationBody, true));
|
|
||||||
// $rawSignature = "Client-Id:" . $notificationHeader['Client-Id'] . "\n"
|
|
||||||
// . "Request-Id:" . $notificationHeader['Request-Id'] . "\n"
|
|
||||||
// . "Request-Timestamp:" . $notificationHeader['Request-Timestamp'] . "\n"
|
|
||||||
// . "Request-Target:" . $notificationPath . "\n"
|
|
||||||
// . "Digest:" . $digest;
|
|
||||||
|
|
||||||
// $signature = base64_encode(hash_hmac('sha256', $rawSignature, $secretKey, true));
|
|
||||||
// $finalSignature = 'HMACSHA256=' . $signature;
|
|
||||||
|
|
||||||
// if ($finalSignature == $notificationHeader['Signature']) {
|
|
||||||
|
|
||||||
// $fileHandle = fopen('doku_success.txt', 'w');
|
|
||||||
// fwrite($fileHandle, 'Done');
|
|
||||||
// fclose($fileHandle);
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
|
|
||||||
// } else {
|
|
||||||
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
try {
|
|
||||||
//Set session data
|
|
||||||
$user = User::where('email', $bodyData['customer']['email'])->firstOrNew();
|
|
||||||
Auth::login($user);
|
|
||||||
|
|
||||||
$payment_details = json_decode($user->temp, true);
|
|
||||||
if ($payment_details['expired_on'] >= time() && $bodyData['transaction']['status'] == 'SUCCESS') {
|
|
||||||
session(['payment_details' => $payment_details]);
|
|
||||||
|
|
||||||
$success_model = $payment_details['success_method']['model_name'];
|
|
||||||
$success_function = $payment_details['success_method']['function_name'];
|
|
||||||
$model_full_path = str_replace(' ', '', 'App\Models\ ' . $success_model);
|
|
||||||
$model_full_path::$success_function($identifier);
|
|
||||||
|
|
||||||
// Unset all session data
|
|
||||||
User::where('email', $bodyData['customer']['email'])->update(['temp' => json_encode([])]);
|
|
||||||
session(['payment_details' => []]);
|
|
||||||
Auth::logout();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
// Log the error message
|
|
||||||
Log::error('Doku error occurred: ' . $e->getMessage());
|
|
||||||
|
|
||||||
// Optionally handle the exception (e.g., rethrow or show a custom error message)
|
|
||||||
return response()->json(['error' => 'Something went wrong!'], 500);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "submitted";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function storeTempData()
|
|
||||||
{
|
|
||||||
//Store payment data temporary
|
|
||||||
Schema::table('users', function (Blueprint $table) {
|
|
||||||
if (! Schema::hasColumn('users', 'temp')) {
|
|
||||||
$table->text('temp')->nullable();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$payment_details['expired_on'] = time() + 300;
|
|
||||||
User::where('id', auth()->user()->id)->update(['temp' => json_encode($payment_details)]);
|
|
||||||
session(['payment_details' => []]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models\payment_gateway;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class Maxicash extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public static function payment_status($identifier, $transaction_keys = [])
|
|
||||||
{
|
|
||||||
if ($transaction_keys != '') {
|
|
||||||
array_shift($transaction_keys);
|
|
||||||
session(['keys' => $transaction_keys]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function payment_create($identifier)
|
|
||||||
{
|
|
||||||
$identifier = 'maxicash';
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$user = DB::table('users')->where('id', auth()->user()->id)->first();
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
|
|
||||||
$products_name = '';
|
|
||||||
foreach ($payment_details['items'] as $key => $value):
|
|
||||||
if ($key == 0) {
|
|
||||||
$products_name .= $value['title'];
|
|
||||||
} else {
|
|
||||||
$products_name .= ', ' . $value['title'];
|
|
||||||
}
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
$merchant_id = $keys['merchant_id'];
|
|
||||||
$merchant_password = $keys['merchant_password'];
|
|
||||||
|
|
||||||
$data1 = [
|
|
||||||
"PayType" => $identifier,
|
|
||||||
"MerchantID" => $merchant_id,
|
|
||||||
"MerchantPassword" => $merchant_password,
|
|
||||||
"Amount" => (string) round($payment_details['payable_amount'] * 100),
|
|
||||||
"Currency" => $payment_gateway->currency,
|
|
||||||
"Telephone" => $user->phone,
|
|
||||||
"Language" => "en",
|
|
||||||
"Reference" => "MAXI_TXN_" . uniqid(),
|
|
||||||
"accepturl" => $payment_details['success_url'] . '/' . $payment_gateway->identifier,
|
|
||||||
"declineurl" => $payment_details['cancel_url'],
|
|
||||||
"cancelurl" => $payment_details['cancel_url'],
|
|
||||||
"notifyurl" => $payment_details['cancel_url'],
|
|
||||||
];
|
|
||||||
|
|
||||||
$data = json_encode($data1);
|
|
||||||
|
|
||||||
if ($payment_gateway->test_mode == 1) {
|
|
||||||
$url = 'https://api-testbed.maxicashapp.com/payentry?data=' . $data;
|
|
||||||
} else {
|
|
||||||
$url = 'https://api.maxicashapp.com/payentry?data=' . $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $url;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,136 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace App\Models\payment_gateway;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
|
|
||||||
class Sslcommerz extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
public static function payment_status($identifier, $transaction_keys = [])
|
|
||||||
{
|
|
||||||
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', $identifier)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
|
|
||||||
$val_id = urlencode($_POST['val_id']);
|
|
||||||
$store_key = $keys['store_key'];
|
|
||||||
$store_password = $keys['store_password'];
|
|
||||||
|
|
||||||
if ($payment_gateway->test_mode == 1) {
|
|
||||||
$store_key = $keys['store_key'];
|
|
||||||
$store_password = $keys['store_password'];
|
|
||||||
$validation_url = "https://sandbox.sslcommerz.com";
|
|
||||||
} else {
|
|
||||||
$store_key = $keys['store_live_key'];
|
|
||||||
$store_password = $keys['store_live_password'];
|
|
||||||
$validation_url = "https://securepay.sslcommerz.com";
|
|
||||||
}
|
|
||||||
|
|
||||||
$validation_url .= "/validator/api/validationserverAPI.php?val_id=" . $val_id . "&store_id=" . $store_key . "&store_passwd=" . $store_password . "&v=1&format=json";
|
|
||||||
|
|
||||||
$handle = curl_init();
|
|
||||||
curl_setopt($handle, CURLOPT_URL, $validation_url);
|
|
||||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
|
|
||||||
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
|
|
||||||
|
|
||||||
$result = curl_exec($handle);
|
|
||||||
|
|
||||||
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
if ($code == 200 && ! (curl_errno($handle))) {
|
|
||||||
|
|
||||||
$result = json_decode($result, true);
|
|
||||||
|
|
||||||
if ($result['status'] == 'VALIDATED' || $result['status'] == 'VALID') {
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function payment_create($identifier)
|
|
||||||
{
|
|
||||||
$payment_details = session('payment_details');
|
|
||||||
$payment_gateway = DB::table('payment_gateways')->where('identifier', 'sslcommerz')->first();
|
|
||||||
$user = DB::table('users')->where('id', auth()->user()->id)->first();
|
|
||||||
$keys = json_decode($payment_gateway->keys, true);
|
|
||||||
|
|
||||||
$products_name = '';
|
|
||||||
foreach ($payment_details['items'] as $key => $value):
|
|
||||||
if ($key == 0) {
|
|
||||||
$products_name .= $value['title'];
|
|
||||||
} else {
|
|
||||||
$products_name .= ', ' . $value['title'];
|
|
||||||
}
|
|
||||||
endforeach;
|
|
||||||
|
|
||||||
if ($payment_gateway->test_mode == 1):
|
|
||||||
$store_key = $keys['store_key'];
|
|
||||||
$store_password = $keys['store_password'];
|
|
||||||
$direct_api_url = "https://sandbox.sslcommerz.com/gwprocess/v3/api.php";
|
|
||||||
else:
|
|
||||||
$store_key = $keys['store_live_key'];
|
|
||||||
$store_password = $keys['store_live_password'];
|
|
||||||
$direct_api_url = "https://securepay.sslcommerz.com/gwprocess/v3/api.php";
|
|
||||||
endif;
|
|
||||||
|
|
||||||
$post_data = array();
|
|
||||||
$post_data['user_id'] = $user->id;
|
|
||||||
$post_data['payment_type'] = $identifier;
|
|
||||||
$post_data['items_id'] = $payment_details['items'][0]['id'];
|
|
||||||
$post_data['store_id'] = $store_key;
|
|
||||||
$post_data['store_passwd'] = $store_password;
|
|
||||||
$post_data['total_amount'] = round($payment_details['payable_amount']);
|
|
||||||
$post_data['currency'] = "BDT";
|
|
||||||
$post_data['tran_id'] = "SSLCZ_TXN_" . uniqid();
|
|
||||||
$post_data['success_url'] = $payment_details['success_url'] . '/' . $payment_gateway->identifier;
|
|
||||||
$post_data['fail_url'] = $payment_details['cancel_url'];
|
|
||||||
$post_data['cancel_url'] = $payment_details['cancel_url'];
|
|
||||||
|
|
||||||
# CUSTOMER INFORMATION
|
|
||||||
$post_data['cus_name'] = $user->name;
|
|
||||||
$post_data['cus_email'] = $user->email;
|
|
||||||
$post_data['cus_add1'] = $user->address;
|
|
||||||
$post_data['cus_city'] = "";
|
|
||||||
$post_data['cus_state'] = "";
|
|
||||||
$post_data['cus_postcode'] = "";
|
|
||||||
$post_data['cus_country'] = "";
|
|
||||||
$post_data['cus_phone'] = $user->phone;
|
|
||||||
$post_data['cus_fax'] = "";
|
|
||||||
|
|
||||||
$handle = curl_init();
|
|
||||||
curl_setopt($handle, CURLOPT_URL, $direct_api_url);
|
|
||||||
curl_setopt($handle, CURLOPT_TIMEOUT, 30);
|
|
||||||
curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 30);
|
|
||||||
curl_setopt($handle, CURLOPT_POST, 1);
|
|
||||||
curl_setopt($handle, CURLOPT_POSTFIELDS, $post_data);
|
|
||||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); # KEEP IT FALSE IF YOU RUN FROM LOCAL PC
|
|
||||||
|
|
||||||
$content = curl_exec($handle);
|
|
||||||
|
|
||||||
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
$ssl_commerz_response = "";
|
|
||||||
if ($code == 200 && ! (curl_errno($handle))) {
|
|
||||||
curl_close($handle);
|
|
||||||
$ssl_commerz_response = json_decode($content, true);
|
|
||||||
} else {
|
|
||||||
curl_close($handle);
|
|
||||||
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ssl_commerz_response['GatewayPageURL'];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::create('knowledge_bases', function (Blueprint $table) {
|
|
||||||
$table->id();
|
|
||||||
$table->string('title')->unique();
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('knowledge_bases');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
return new class extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*/
|
|
||||||
public function up(): void
|
|
||||||
{
|
|
||||||
Schema::create('knowledge_base_topicks', function (Blueprint $table) {
|
|
||||||
$table->id();
|
|
||||||
$table->bigInteger('knowledge_base_id');
|
|
||||||
$table->string('topic_name');
|
|
||||||
$table->text('description');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*/
|
|
||||||
public function down(): void
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('knowledge_base_topicks');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.2 KiB |
@ -1,124 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Assign Permission'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Admin Permissions') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.admins.index') }}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-arrow-alt-left"></span>
|
|
||||||
<span>{{ get_phrase('Back') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@php
|
|
||||||
// MAKE SURE TO KEEP A PERMISSION FOR USERS AND THEME
|
|
||||||
$routes = [
|
|
||||||
'admin.dashboard' => get_phrase('Dashboard'),
|
|
||||||
'admin.categories' => get_phrase('Category'),
|
|
||||||
'admin.courses' => get_phrase('Course'),
|
|
||||||
'admin.bootcamps' => get_phrase('Bootcamp'),
|
|
||||||
'admin.student.enroll' => get_phrase('Enrollment'),
|
|
||||||
'admin.enroll.history' => get_phrase('Enroll History'),
|
|
||||||
'admin.revenue' => get_phrase('Admin Revenue'),
|
|
||||||
'admin.instructor.revenue' => get_phrase('Instructor Revenue'),
|
|
||||||
'admin.purchase.history' => get_phrase('Purchase history'),
|
|
||||||
'admin.instructor.index' => get_phrase('Instructor'),
|
|
||||||
'admin.admins.index' => get_phrase('Admin'),
|
|
||||||
'admin.student.index' => get_phrase('Student'),
|
|
||||||
'admin.message' => get_phrase('Message'),
|
|
||||||
'admin.newsletter' => get_phrase('Newsletter'),
|
|
||||||
'admin.subscribed_user' => get_phrase('Newsletter Subscriber'),
|
|
||||||
'admin.contacts' => get_phrase('Contact User'),
|
|
||||||
'admin.offline.payments' => get_phrase('Offline Payment'),
|
|
||||||
'admin.coupons' => get_phrase('Coupon'),
|
|
||||||
'admin.blogs' => get_phrase('Blog'),
|
|
||||||
'admin.pending.blog' => get_phrase('Pending Blog List'),
|
|
||||||
'admin.blog.category' => get_phrase('Blog Category'),
|
|
||||||
'admin.blog.settings' => get_phrase('Blog Settings'),
|
|
||||||
|
|
||||||
'admin.system.settings' => get_phrase('System Settings'),
|
|
||||||
'admin.website.settings' => get_phrase('Website Settings'),
|
|
||||||
'admin.payment.settings' => get_phrase('Payment Settings'),
|
|
||||||
'admin.manage.language' => get_phrase('Language Settings'),
|
|
||||||
'admin.live.class.settings' => get_phrase('Live Class Settings'),
|
|
||||||
'admin.certificate.settings' => get_phrase('Certificate'),
|
|
||||||
'admin.open.ai.settings' => get_phrase('Open AI Settings'),
|
|
||||||
'admin.seo.settings' => get_phrase('SEO Settings'),
|
|
||||||
'admin.about' => get_phrase('About'),
|
|
||||||
];
|
|
||||||
$permission_row = DB::table('permissions')
|
|
||||||
->where('admin_id', $admin->id)
|
|
||||||
->first();
|
|
||||||
$permissions = json_decode($permission_row->permissions ?? '{}', true);
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-8">
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<div class="col-6 pt-3">
|
|
||||||
<p class="column-title">{{ get_phrase('Assign permission for') }}: {{ $admin->name }}</p>
|
|
||||||
</div>
|
|
||||||
<div class="pb-3">
|
|
||||||
<small> <strong>{{ get_phrase('Note') }}</strong> :
|
|
||||||
{{ get_phrase('You can toggle the switch for enabling or disabling a feature to access') }}</small>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table eTable">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{{ get_phrase('Feature') }}</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($routes as $route => $title)
|
|
||||||
<tr>
|
|
||||||
<td>{{ $title }}</td>
|
|
||||||
<td>
|
|
||||||
<!-- Bool Switch-->
|
|
||||||
<input type="checkbox" class="form-check-input" id="{{ $admin->id . '-' . $route }}" data-switch="bool" onchange="setPermission('{{ $admin->id }}', '{{ $route }}')" @if (is_array($permissions) && in_array($route, $permissions)) checked @endif>
|
|
||||||
<label for="{{ $admin->id . '-' . $route }}" data-on-label="On" data-off-label="Off"></label>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div> <!-- end card body-->
|
|
||||||
</div> <!-- end card -->
|
|
||||||
</div><!-- end col-->
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function setPermission(user_id, permission) {
|
|
||||||
$.ajax({
|
|
||||||
type: "post",
|
|
||||||
url: "{{ route('admin.admins.permission.store') }}/" + user_id,
|
|
||||||
data: {
|
|
||||||
user_id: user_id,
|
|
||||||
permission: permission,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
if (response == 1) {
|
|
||||||
success("{{ get_phrase('Permission updated') }}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Knowledge_base'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<!-- Mani section header and breadcrumb -->
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
<span>{{ get_phrase('Add Article') }}</span>
|
|
||||||
</h4>
|
|
||||||
<a href="{{route('admin.articles',['id'=> $articleTitle->id])}}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-arrow-left"></span>
|
|
||||||
<span>{{ get_phrase('Back') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row ">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<h5 class="pb-5">{{$articleTitle->title}}</n5>
|
|
||||||
<form action="{{route('admin.articles.store')}}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="title">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control" name="title" id="title"
|
|
||||||
placeholder="{{ get_phrase('Enter Article title') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="summernote-basic">{{ get_phrase('Description') }}</label>
|
|
||||||
<textarea name="description" class="form-control ol-form-control text_editor"></textarea>
|
|
||||||
</div>
|
|
||||||
<input type="hidden" name='topick_id' value="{{$articleTitle->id}}">
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Add Article') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function stopProp(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
@php
|
|
||||||
$article = App\Models\Knowledge_base_topick::where('id', $id)->first();
|
|
||||||
@endphp
|
|
||||||
<form action="{{ route('admin.articles.update', $id) }}" method="post">@csrf
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="topic_name" class="form-label ol-form-label">{{ get_phrase('topic_name') }}</label>
|
|
||||||
<input type="text" name="topic_name" class="form-control ol-form-control" id="topic_name" value="{{ $article->topic_name }}" placeholder="{{ get_phrase('Topick Name') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="description" class="form-label ol-form-label">{{ get_phrase('Description') }}</label>
|
|
||||||
<textarea name="description" id="description" required>{{ $article->description }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Submit') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$('#description').summernote({
|
|
||||||
height: 180, // set editor height
|
|
||||||
minHeight: null, // set minimum height of editor
|
|
||||||
maxHeight: null, // set maximum height of editor
|
|
||||||
focus: true, // set focus to editable area after initializing summernote
|
|
||||||
toolbar: [
|
|
||||||
['color', ['color']],
|
|
||||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
|
||||||
['fontsize', ['fontsize']],
|
|
||||||
['para', ['ul', 'ol']],
|
|
||||||
['table', ['table']],
|
|
||||||
['insert', ['link']]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Knowledge_base'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{$articleTitle->title}}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.articles.create',['id'=>$articleTitle->id]) }}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add Article') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div id="accordion" class="custom-accordion mb-4">
|
|
||||||
<div class="ol-card p-20px">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<ul class="ol-my-accordion">
|
|
||||||
@if (count($articles) > 0)
|
|
||||||
|
|
||||||
@foreach ($articles as $key => $article)
|
|
||||||
<li class="single-accor-item">
|
|
||||||
<div class="accordion-btn-wrap">
|
|
||||||
<div class="accordion-btn-title d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/firstline-gray-16.svg" alt="">
|
|
||||||
<h3 class="title">{{ $key+1 }}. {{ $article->topic_name }}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-button-buttons">
|
|
||||||
<a onclick="ajaxModal('{{ route('modal', ['admin.articles.edit', 'id' => $article->id]) }}', '{{ get_phrase('Edit Articles') }}')" data-bs-toggle="tooltip" title="{{ get_phrase('Edit') }}" href="#" class="edit"><span class="fi fi-rr-pen-clip"></span></a>
|
|
||||||
<a onclick="confirmModal('{{ route('admin.articles.delete', $article->id) }}')" data-bs-toggle="tooltip" title="{{ get_phrase('Delete') }}" href="#" class="delete"><span class="fi-rr-trash"></span></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="accoritem-body d-hidden">
|
|
||||||
<div class="py-10px">
|
|
||||||
{!! removeScripts($article->description) !!}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
@if (count($articles) > 0)
|
|
||||||
<div
|
|
||||||
class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($articles) . ' ' . get_phrase('of') . ' ' . $articles->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $articles->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function stopProp(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@ -1,257 +0,0 @@
|
|||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
$('a[href="#"]').on('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function redirectTo(url) {
|
|
||||||
$(location).attr('href', url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function actionTo(url, type = "get") {
|
|
||||||
//Start prepare get url to post value
|
|
||||||
var jsonFormate = '{}';
|
|
||||||
if (type == 'post') {
|
|
||||||
let pieces = url.split(/[\s?]+/);
|
|
||||||
let lastString = pieces[pieces.length - 1];
|
|
||||||
jsonFormate = '{"' + lastString.replace('=', '":"').replace("&", '","').replace("=", '":"').replace("&",
|
|
||||||
'","').replace("=", '":"').replace("&", '","').replace("=", '":"').replace("&", '","').replace("=",
|
|
||||||
'":"').replace("&", '","').replace("=", '":"').replace("&", '","').replace("=", '":"').replace("&",
|
|
||||||
'","').replace("=", '":"').replace("&", '","').replace("=", '":"').replace("&", '","').replace("=",
|
|
||||||
'":"').replace("&", '","').replace("=", '":"').replace("&", '","').replace("=", '":"').replace("&",
|
|
||||||
'","').replace("=", '":"').replace("&", '","').replace("=", '":"').replace("&", '","') + '"}';
|
|
||||||
}
|
|
||||||
jsonFormate = JSON.parse(jsonFormate);
|
|
||||||
//End prepare get url to post value
|
|
||||||
$.ajax({
|
|
||||||
type: type,
|
|
||||||
url: url,
|
|
||||||
data: jsonFormate,
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
distributeServerResponse(response);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//Server response distribute
|
|
||||||
function distributeServerResponse(response) {
|
|
||||||
try {
|
|
||||||
JSON.parse(response);
|
|
||||||
var isValidJson = true;
|
|
||||||
} catch (error) {
|
|
||||||
var isValidJson = false;
|
|
||||||
}
|
|
||||||
if (isValidJson) {
|
|
||||||
response = JSON.parse(response);
|
|
||||||
|
|
||||||
//For reload after submission
|
|
||||||
if (typeof response.reload != "undefined" && response.reload != 0) {
|
|
||||||
location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
//For redirect to another url
|
|
||||||
if (typeof response.redirectTo != "undefined" && response.redirectTo != 0) {
|
|
||||||
$(location).attr('href', response.redirectTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
//for show a element
|
|
||||||
if (typeof response.show != "undefined" && response.show != 0 && $(response.show).length) {
|
|
||||||
$(response.show).css('display', 'inline-block');
|
|
||||||
}
|
|
||||||
//for hide a element
|
|
||||||
if (typeof response.hide != "undefined" && response.hide != 0 && $(response.hide).length) {
|
|
||||||
$(response.hide).hide();
|
|
||||||
}
|
|
||||||
//for fade in a element
|
|
||||||
if (typeof response.fadeIn != "undefined" && response.fadeIn != 0 && $(response.fadeIn).length) {
|
|
||||||
$(response.fadeIn).fadeIn();
|
|
||||||
}
|
|
||||||
//for fade out a element
|
|
||||||
if (typeof response.fadeOut != "undefined" && response.fadeOut != 0 && $(response.fadeOut).length) {
|
|
||||||
$(response.fadeOut).fadeOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
//For adding a class
|
|
||||||
if (typeof response.addClass != "undefined" && response.addClass != 0 && $(response.addClass.elem).length) {
|
|
||||||
$(response.addClass.elem).addClass(response.addClass.content);
|
|
||||||
}
|
|
||||||
//For remove a class
|
|
||||||
if (typeof response.removeClass != "undefined" && response.removeClass != 0 && $(response.removeClass.elem)
|
|
||||||
.length) {
|
|
||||||
$(response.removeClass.elem).removeClass(response.removeClass.content);
|
|
||||||
}
|
|
||||||
//For toggle a class
|
|
||||||
if (typeof response.toggleClass != "undefined" && response.toggleClass != 0 && $(response.toggleClass.elem)
|
|
||||||
.length) {
|
|
||||||
$(response.toggleClass.elem).toggleClass(response.toggleClass.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For showing error message
|
|
||||||
if (typeof response.error != "undefined" && response.error != 0) {
|
|
||||||
error(response.error);
|
|
||||||
}
|
|
||||||
//For showing warning message
|
|
||||||
if (typeof response.warning != "undefined" && response.warning != 0) {
|
|
||||||
warning(response.warning);
|
|
||||||
}
|
|
||||||
//For showing success message
|
|
||||||
if (typeof response.success != "undefined" && response.success != 0) {
|
|
||||||
success(response.success);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For replace texts in a specific element
|
|
||||||
if (typeof response.text != "undefined" && response.text != 0 && $(response.text.elem).length) {
|
|
||||||
$(response.text.elem).text(response.text.content);
|
|
||||||
}
|
|
||||||
//For replace elements in a specific element
|
|
||||||
if (typeof response.html != "undefined" && response.html != 0 && $(response.html.elem).length) {
|
|
||||||
$(response.html.elem).html(response.html.content);
|
|
||||||
}
|
|
||||||
//For replace elements in a specific element
|
|
||||||
if (typeof response.load != "undefined" && response.load != 0 && $(response.load.elem).length) {
|
|
||||||
$(response.load.elem).html(response.load.content);
|
|
||||||
}
|
|
||||||
//For appending elements
|
|
||||||
if (typeof response.append != "undefined" && response.append != 0 && $(response.append.elem).length) {
|
|
||||||
$(response.append.elem).append(response.append.content);
|
|
||||||
}
|
|
||||||
//Fo prepending elements
|
|
||||||
if (typeof response.prepend != "undefined" && response.prepend != 0 && $(response.prepend.elem).length) {
|
|
||||||
$(response.prepend.elem).prepend(response.prepend.content);
|
|
||||||
}
|
|
||||||
//For appending elements after a element
|
|
||||||
if (typeof response.after != "undefined" && response.after != 0 && $(response.after.elem).length) {
|
|
||||||
$(response.after.elem).after(response.after.content);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For function call
|
|
||||||
if (typeof response.functionCall != "undefined" && response.functionCall != 0) {
|
|
||||||
eval(response.functionCall)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the browser URL and add a new entry to the history
|
|
||||||
if (typeof response.pushState != "undefined" && response.pushState != 0) {
|
|
||||||
history.pushState({}, response.pushState.title, response.pushState.url);
|
|
||||||
}
|
|
||||||
//For form validation Error
|
|
||||||
if (typeof response.validationError != "undefined" && response.validationError != 0) {
|
|
||||||
$('.form-validation-error-label').remove();
|
|
||||||
let errorList = '<ul>';
|
|
||||||
Object.keys(response.validationError).forEach(key => {
|
|
||||||
if ($("[name=" + key + "]").length > 0) {
|
|
||||||
$("[name=" + key + "]").after(
|
|
||||||
'<small class="text-danger text-12px form-validation-error-label">' + response
|
|
||||||
.validationError[key][0] + '</small>');
|
|
||||||
} else if ($("input[name='" + key + "[]']").length > 0) {
|
|
||||||
$("input[name='" + key + "[]']").after(
|
|
||||||
'<small class="text-danger text-12px form-validation-error-label">' +
|
|
||||||
response.validationError[key][0] + '</small>');
|
|
||||||
}
|
|
||||||
|
|
||||||
errorList = errorList + '<li>' + response.validationError[key][0] + '</li>';
|
|
||||||
});
|
|
||||||
errorList = errorList + '</ul>';
|
|
||||||
|
|
||||||
error(errorList);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof response.script != "undefined" && response.script != 0) {
|
|
||||||
response.script
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadView(url, element, check_already_loaded) {
|
|
||||||
if ($(element).text() == '' && check_already_loaded || !check_already_loaded) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
success: function(response) {
|
|
||||||
$(element).html(response);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadPDF(elem = ".print-table", fileName = 'data') {
|
|
||||||
$('.print-d-none:not(.row, .ol-header, .ol-card)').addClass('d-none');
|
|
||||||
// Get the table element as HTML
|
|
||||||
const table = document.querySelector(elem);
|
|
||||||
|
|
||||||
// Options for html2pdf
|
|
||||||
const options = {
|
|
||||||
margin: 0.5,
|
|
||||||
filename: fileName,
|
|
||||||
image: {
|
|
||||||
type: 'jpeg',
|
|
||||||
quality: 0.98
|
|
||||||
},
|
|
||||||
html2canvas: {
|
|
||||||
scale: 2
|
|
||||||
},
|
|
||||||
jsPDF: {
|
|
||||||
unit: 'in',
|
|
||||||
format: 'letter',
|
|
||||||
orientation: 'portrait'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Generate PDF from the table
|
|
||||||
if (html2pdf().from(table).set(options).save()) {
|
|
||||||
setInterval(() => {
|
|
||||||
$('.print-d-none').removeClass('d-none');
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function downloadTableAsCSV(elem, filename = 'data.csv') {
|
|
||||||
// Select the table element
|
|
||||||
var table = document.querySelector(elem);
|
|
||||||
|
|
||||||
// Initialize CSV string
|
|
||||||
var csv = [];
|
|
||||||
|
|
||||||
// Iterate over table rows
|
|
||||||
var rows = table.rows;
|
|
||||||
for (var i = 0; i < rows.length; i++) {
|
|
||||||
var row = [],
|
|
||||||
cols = rows[i].cells;
|
|
||||||
|
|
||||||
// Iterate over table cells
|
|
||||||
for (var j = 0; j < cols.length; j++) {
|
|
||||||
row.push(cols[j].innerText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Join the row elements with commas
|
|
||||||
csv.push(row.join(','));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Join the rows with newline character
|
|
||||||
var csvData = csv.join('\n');
|
|
||||||
|
|
||||||
// Create a Blob object containing the CSV data
|
|
||||||
var blob = new Blob([csvData], {
|
|
||||||
type: 'text/csv'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create a temporary link to trigger the download
|
|
||||||
var link = document.createElement('a');
|
|
||||||
link.href = window.URL.createObjectURL(blob);
|
|
||||||
link.download = filename + '.csv';
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.trigger('click');
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadImage(elem, preview) {
|
|
||||||
var x = URL.createObjectURL(event.target.files[0]);
|
|
||||||
console.log(x);
|
|
||||||
$(preview).attr('src', x);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,372 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Course Manager'))
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Manage Courses') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.course.create') }}"class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add New Course') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row g-2 g-sm-3 mb-3 row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-4 row-cols-xl-5">
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('admin.courses', ['status' => 'active']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $active_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Active courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('admin.courses', ['status' => 'pending']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $pending_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Pending courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('admin.courses', ['status' => 'upcoming']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $upcoming_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Upcoming courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('admin.courses', ['price' => 'free']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $free_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Free courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('admin.courses', ['price' => 'paid']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $paid_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Paid courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Start Admin area -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="ol-card">
|
|
||||||
<div class="ol-card-body p-3 mb-5">
|
|
||||||
<div class="row mt-3 mb-4">
|
|
||||||
<div class="col-md-6 d-flex align-items-center gap-3">
|
|
||||||
<div class="custom-dropdown ms-2">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item export-btn" href="#" onclick="downloadPDF('.print-table', 'course-list')"><i class="fi-rr-file-pdf"></i> {{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item export-btn" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="custom-dropdown dropdown-filter @if (!isset($_GET) || (isset($_GET) && count($_GET) == 0)) @endif">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
<i class="fi-rr-filter me-2"></i>
|
|
||||||
{{ get_phrase('Filter') }}
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET))
|
|
||||||
<span class="text-12px">
|
|
||||||
({{count($_GET)}})
|
|
||||||
</span>
|
|
||||||
@endif
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list w-250px">
|
|
||||||
<li>
|
|
||||||
<form id="filter-dropdown" action="{{ route('admin.courses') }}" method="get">
|
|
||||||
<div class="filter-option d-flex flex-column gap-3">
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Category') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="category" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}</option>
|
|
||||||
|
|
||||||
@foreach (App\Models\Category::where('parent_id', 0)->orderBy('title', 'desc')->get() as $category)
|
|
||||||
<option value="{{ $category->slug }}"@if (isset($parent_cat) && $parent_cat == $category->slug) selected @endif>
|
|
||||||
{{ $category->title }}</option>
|
|
||||||
|
|
||||||
@foreach ($category->childs as $sub_category)
|
|
||||||
<option value="{{ $sub_category->slug }}"@if (isset($child_cat) && $child_cat == $sub_category->slug) selected @endif>
|
|
||||||
--{{ $sub_category->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Status') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="status" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option value="active"@if (isset($status) && $status == 'active') selected @endif>{{ get_phrase('Active') }} </option>
|
|
||||||
<option value="inactive"@if (isset($status) && $status == 'inactive') selected @endif>{{ get_phrase('Inactive') }} </option>
|
|
||||||
<option value="pending"@if (isset($status) && $status == 'pending') selected @endif>{{ get_phrase('Pending') }} </option>
|
|
||||||
<option value="upcoming"@if (isset($status) && $status == 'upcoming') selected @endif>{{ get_phrase('Upcoming') }} </option>
|
|
||||||
<option value="private"@if (isset($status) && $status == 'private') selected @endif>{{ get_phrase('Private') }} </option>
|
|
||||||
<option value="draft"@if (isset($status) && $status == 'draft') selected @endif>{{ get_phrase('Draft') }} </option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Instructor') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="instructor" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
@foreach (App\Models\Course::select('user_id')->distinct()->get() as $course)
|
|
||||||
<option value="{{ $course->user_id }}"@if (isset($instructor) && $instructor == $course->user_id) selected @endif>
|
|
||||||
{{ ucfirst(get_user_info($course->user_id)->name) }}
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Price') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="price" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option value="free"@if (isset($price) && $price == 'free') selected @endif>
|
|
||||||
{{ get_phrase('Free') }}</option>
|
|
||||||
<option value="paid"@if (isset($price) && $price == 'paid') selected @endif>
|
|
||||||
{{ get_phrase('Paid') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button d-flex justify-content-end align-items-center mt-3">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Apply') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET) > 0)
|
|
||||||
<a href="{{ route('admin.courses') }}" class="me-2" data-bs-toggle="tooltip" title="{{ get_phrase('Clear') }}"><i class="fi-rr-cross-circle"></i></a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mt-3 mt-md-0">
|
|
||||||
<form action="{{ route('admin.courses') }}" method="get">
|
|
||||||
<div class="row row-gap-3">
|
|
||||||
<div class="col-md-9">
|
|
||||||
<div class="search-input flex-grow-1">
|
|
||||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="{{ get_phrase('Search Title') }}" class="ol-form-control form-control" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<button type="submit" class="btn ol-btn-primary w-100" id="submit-button">{{ get_phrase('Search') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
@if ($courses->count() > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($courses) . ' ' . get_phrase('of') . ' ' . $courses->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive overflow-auto course_list overflow-auto" id="course_list">
|
|
||||||
<table class="table eTable eTable-2 print-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('Title') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Category') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Lesson & Section') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Enrolled Student') }}</th>
|
|
||||||
<th scope="col" class="print-d-none">{{ get_phrase('Status') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Price') }}</th>
|
|
||||||
<th scope="col" class="print-d-none">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($courses as $key => $row)
|
|
||||||
@php
|
|
||||||
$query = App\Models\Watch_history::where('course_id', $row->id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
$query1 = App\Models\Lesson::where('course_id', $row->id)
|
|
||||||
->orderBy('sort', 'asc')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (isset($query->watching_lesson_id) && $query->watching_lesson_id != '') {
|
|
||||||
$watching_lesson_id = $query->watching_lesson_id;
|
|
||||||
} elseif (isset($query1->id)) {
|
|
||||||
$watching_lesson_id = $query1->id;
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ ++$key }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
<h4 class="title fs-14px">
|
|
||||||
<a href="{{ route('admin.course.edit', [$row->id, 'tab' => 'curriculum']) }}">{{ ucfirst($row->title) }}</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.courses', ['instructor' => $row->user_id]) }}">
|
|
||||||
<p class="sub-title2 text-12px">
|
|
||||||
{{ get_phrase('Instructor') }}:
|
|
||||||
{{ get_user_info($row->user_id)->name }}</p>
|
|
||||||
<p class="sub-title2 text-12px">{{ get_phrase('Email') }}:
|
|
||||||
{{ get_user_info($row->user_id)->email }}</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<a href="{{ route('admin.courses', ['category' => $row->category->slug ?? '']) }}">{{ category_by_course($row->category_id)->title }}</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<a href="{{ route('admin.course.edit', [$row->id, 'tab' => 'curriculum']) }}">
|
|
||||||
<p>{{ get_phrase('Lesson') }}: {{ lesson_count($row->id) }} </p>
|
|
||||||
<p> {{ get_phrase('Section') }}: {{ section_count($row->id) }} </p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<p>
|
|
||||||
{{ course_enrollments($row->id). ' ' .get_phrase('students') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
<span class="badge bg-{{ $row->status }}">{{ get_phrase(ucfirst($row->status)) }}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name min-w-150px">
|
|
||||||
@if ($row->is_paid == 0)
|
|
||||||
<p class="eBadge ebg-soft-success">
|
|
||||||
{{ get_phrase('Free') }}
|
|
||||||
</p>
|
|
||||||
@elseif($row->discount_flag == 1)
|
|
||||||
<p>{{ currency($row->discounted_price) }} <del>{{ currency($row->price) }}</del></p>
|
|
||||||
@else
|
|
||||||
<p>{{ currency($row->price) }}</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" target="_blank" href="{{ route('course.details', $row->slug) }}">{{ get_phrase('View Course On Frontend') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" target="_blank" href="{{ route('course.player', ['slug' => $row->slug]) }}">{{ get_phrase('Go To Course Playing Page') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ route('admin.course.edit', [$row->id, 'tab' => 'basic']) }}">{{ get_phrase('Edit Course') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.course.duplicate', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Duplicate Course') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
@if ($row->status == 'active')
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.course.status', ['type' => 'inactive', 'id' => $row->id]) }}')" href="#">{{ get_phrase('Make As Inactive') }}</a>
|
|
||||||
</li>
|
|
||||||
@elseif($row->status == 'pending')
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="ajaxModal('{{ route('view', ['path' => 'admin.course.course_approval', 'course_id' => $row->id]) }}', '{{ get_phrase('Write a congratulatory message') }}')" href="#">{{ get_phrase('Make As Active') }}</a>
|
|
||||||
</li>
|
|
||||||
@else
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.course.status', ['type' => 'active', 'id' => $row->id]) }}')" href="#">{{ get_phrase('Make As Active') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.course.delete', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Delete Course') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($courses) . ' ' . get_phrase('of') . ' ' . $courses->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $courses->links() }}
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- End Admin area -->
|
|
||||||
@endsection
|
|
||||||
@ -1,138 +0,0 @@
|
|||||||
@php
|
|
||||||
$sections = App\Models\Section::where('course_id', $id)->orderBy('sort')->get();
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-primary ol-alert-primary ol-alert-sm mb-3" role="alert">
|
|
||||||
<p class="title2 fs-14px d-flex align-items-center">{{ get_phrase('Lesson type') }}:
|
|
||||||
@if ($lesson_type == 'html5')
|
|
||||||
{{ get_phrase('Video url') . ' [.mp4]' }}
|
|
||||||
@elseif ($lesson_type == 'video')
|
|
||||||
{{ get_phrase('Video file') }}
|
|
||||||
@elseif ($lesson_type == 'youtube' || $lesson_type == 'academy cloud' || $lesson_type == 'vimeo')
|
|
||||||
{{ ucfirst(get_phrase($lesson_type)) }} {{ get_phrase('Video') }}
|
|
||||||
@elseif($lesson_type == 'google_drive_video')
|
|
||||||
{{ get_phrase('Google drive video') }}
|
|
||||||
@elseif($lesson_type == 'document')
|
|
||||||
{{ get_phrase('Document file') }}
|
|
||||||
@elseif ($lesson_type == 'scorm')
|
|
||||||
{{ get_phrase('Scorm content') }}
|
|
||||||
@else
|
|
||||||
{{ ucfirst($lesson_type) }}
|
|
||||||
@endif
|
|
||||||
<a onclick="ajaxModal('{{ route('modal', ['admin.course.lesson_type', 'id' => $id]) }}', '{{ get_phrase('Sort sections') }}')"
|
|
||||||
class="btn text-primary ms-auto p-0 text-14px" href="javascript:void(0)">{{ get_phrase('Change') }} <i
|
|
||||||
class="fi-rr-arrow-alt-circle-right"></i></a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ACTUAL LESSON ADDING FORM -->
|
|
||||||
<form class="ajaxFormSubmission" action="{{ route('admin.lesson.store') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<input type="hidden" name="course_id" value="{{ $id }}">
|
|
||||||
<input type="hidden" name="lesson_type" value="{{ $lesson_type }}">
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Section') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="section_id" required>
|
|
||||||
@foreach ($sections as $section)
|
|
||||||
<option value="{{ $section->id }}">{{ $section->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($lesson_type == 'youtube')
|
|
||||||
@include('admin.course.youtube_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'academy_cloud')
|
|
||||||
@include('admin.course.academy_cloud_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'vimeo')
|
|
||||||
@include('admin.course.vimeo_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'html5')
|
|
||||||
@include('admin.course.html5_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'video')
|
|
||||||
@include('admin.course.video_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'amazon-s3')
|
|
||||||
@include('amazon_s3_type_lesson_add.php')
|
|
||||||
@elseif ($lesson_type == 'google_drive_video')
|
|
||||||
@include('admin.course.google_drive_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'document')
|
|
||||||
@include('admin.course.document_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'text')
|
|
||||||
@include('admin.course.text_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'image')
|
|
||||||
@include('admin.course.image_file_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'iframe')
|
|
||||||
@include('admin.course.iframe_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'scorm')
|
|
||||||
@include('admin.course.scorm_type_lesson_add')
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Summary') }}</label>
|
|
||||||
<textarea name="summary" class="form-control text_editor"></textarea>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group mb-3 d-none">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Do you want to keep it free as a preview lesson') }}
|
|
||||||
?</label>
|
|
||||||
<br>
|
|
||||||
<input type="checkbox" name="free_lesson" id="free_lesson" value="1" class="form-check-input">
|
|
||||||
<label for="free_lesson">{{ get_phrase('Mark as free lesson') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn ol-btn-primary ol-btn-sm w-100 formSubmissionBtn" type="submit"
|
|
||||||
name="button">{{ get_phrase('Add lesson') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function ajax_get_video_details(url) {
|
|
||||||
$('#perloader').show();
|
|
||||||
if (checkURLValidity(url)) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('get.video.details') }}",
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
url: url
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log(response);
|
|
||||||
jQuery('#duration').val(response.duration);
|
|
||||||
$('#perloader').hide();
|
|
||||||
$('#invalid_url').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#invalid_url').show();
|
|
||||||
$('#perloader').hide();
|
|
||||||
jQuery('#duration').val('');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkURLValidity(video_url) {
|
|
||||||
var youtubePregMatch =
|
|
||||||
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
|
||||||
var vimeoPregMatch = /^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/;
|
|
||||||
if (video_url.match(youtubePregMatch)) {
|
|
||||||
return true;
|
|
||||||
} else if (vimeoPregMatch.test(video_url)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@include('admin.init')
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
@php
|
|
||||||
$lessons = App\Models\Lesson::where('id', $id)->first();
|
|
||||||
$sections = App\Models\Section::where('course_id', $lessons->course_id)
|
|
||||||
->orderBy('sort')
|
|
||||||
->get();
|
|
||||||
$select_section = App\Models\Section::where('id', $lessons->section_id)->value('title');
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-info d-flex align-items-center py-2" role="alert">
|
|
||||||
{{ get_phrase('Lesson type') }}:
|
|
||||||
@if ($lessons->lesson_type == 'html5')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Video url') . ' [.mp4]' }}</strong>
|
|
||||||
@elseif ($lessons->lesson_type == 'system-video')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Video file') }}</strong>
|
|
||||||
@elseif ($lessons->lesson_type == 'scorm')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Scorm file') }}</strong>
|
|
||||||
@elseif ($lessons->video_type == 'youtube' || $lessons->video_type == 'vimeo')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase($lessons->video_type) }} {{ get_phrase('Video') }} </strong>
|
|
||||||
@elseif($lessons->lesson_type == 'google_drive_video')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Google drive video') }}</strong>
|
|
||||||
@elseif($lessons->lesson_type == 'document_type')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Document file') }}</strong>
|
|
||||||
@else
|
|
||||||
<strong class="text-capitalize ms-1">{{ $lessons->lesson_type }}</strong>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ACTUAL LESSON ADDING FORM -->
|
|
||||||
<form class="ajaxFormSubmission" action="{{ route('admin.lesson.edit') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<input type="hidden" name="id" value="{{ $id }}">
|
|
||||||
<input type="hidden" name="lesson_type" value="{{ $lessons->lesson_type }}">
|
|
||||||
<div class="form-group eForm-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" value="{{ $lessons->title }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Section') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="section_id" required>
|
|
||||||
@foreach ($sections as $section)
|
|
||||||
<option value="{{ $section->id }}" @if ($lessons->section_id == $section->id) selected @endif>
|
|
||||||
{{ $section->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($lessons->lesson_type == 'video-url')
|
|
||||||
@include('admin.course.youtube_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'vimeo-url')
|
|
||||||
@include('admin.course.vimeo_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'system-video')
|
|
||||||
@include('admin.course.video_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'scorm')
|
|
||||||
@include('admin.course.scorm_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'html5')
|
|
||||||
@include('admin.course.html5_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'google_drive')
|
|
||||||
@include('admin.course.google_drive_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'document_type')
|
|
||||||
@include('admin.course.document_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'text')
|
|
||||||
@include('admin.course.text_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'image')
|
|
||||||
@include('admin.course.image_file_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'iframe')
|
|
||||||
@include('admin.course.iframe_type_lesson_edit')
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('summary') }}</label>
|
|
||||||
<textarea name="summary" class="form-control text_editor">{{ $lessons->summary }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2 d-none">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Do you want to keep it free as a preview lesson') }} ?</label>
|
|
||||||
<br>
|
|
||||||
<input type="checkbox" name="free_lesson" id="free_lesson" value="1">
|
|
||||||
<label for="free_lesson">{{ get_phrase('Mark as free lesson') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn ol-btn-primary ol-btn-sm w-100 formSubmissionBtn" type="submit"
|
|
||||||
name="button">{{ get_phrase('Update lesson') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function ajax_get_video_details(url) {
|
|
||||||
$('#perloader').show();
|
|
||||||
if (checkURLValidity(url)) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('get.video.details') }}",
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
url: url
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log(response);
|
|
||||||
jQuery('#duration').val(response.duration);
|
|
||||||
$('#perloader').hide();
|
|
||||||
$('#invalid_url').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#invalid_url').show();
|
|
||||||
$('#perloader').hide();
|
|
||||||
jQuery('#duration').val('');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkURLValidity(video_url) {
|
|
||||||
var youtubePregMatch =
|
|
||||||
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
|
||||||
var vimeoPregMatch = /^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/;
|
|
||||||
if (video_url.match(youtubePregMatch)) {
|
|
||||||
return true;
|
|
||||||
} else if (vimeoPregMatch.test(video_url)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@include('admin.init')
|
|
||||||
@ -1,172 +0,0 @@
|
|||||||
@php
|
|
||||||
$course = App\Models\Course::where('id', $id)->first();
|
|
||||||
|
|
||||||
$selected_lesson = 'youtube';
|
|
||||||
if (isset($param3) && !empty($param3)) {
|
|
||||||
$selected_lesson = $param3;
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-primary ol-alert-primary ol-alert-sm mb-3" role="alert">
|
|
||||||
<p class="title2 fs-14px">{{ get_phrase('Course') }}:
|
|
||||||
<span class="title">{{ $course->title }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form action="">
|
|
||||||
<input id="course_id_for_lesson" type="hidden" value="" name="course_id_for_lesson">
|
|
||||||
<div class="ol-modal-form">
|
|
||||||
<h6 class="title fs-16px mb-3">{{ get_phrase('Select lesson type') }}</h6>
|
|
||||||
<div class="row row-12px row-cols-1 row-cols-sm-2 mb-20px">
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-youtube">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-square-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('YouTube Video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-youtube" value="youtube" @if ($selected_lesson == 'youtube') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-vimeo">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-circle-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Vimeo Video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-vimeo" value="vimeo" @if ($selected_lesson == 'vimeo') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-videofile">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Video file') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-videofile" value="video" @if ($selected_lesson == 'video') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-url">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/link-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Video url [ .mp4 ]') }}</p>
|
|
||||||
</div>
|
|
||||||
<input value="html5" class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-url">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-drive">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/document-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Google drive video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-drive" value="google_drive_video"
|
|
||||||
@if ($selected_lesson == 'google_drive_video') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-document">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/document-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Document file') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-document" value="document" @if ($selected_lesson == 'document') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-text">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/text-block-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Text') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-text" value="text"
|
|
||||||
@if ($selected_lesson == 'text') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-image">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Image') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-image" value="image"
|
|
||||||
@if ($selected_lesson == 'image') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-iframe">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Iframe embed') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-iframe" value="iframe"
|
|
||||||
@if ($selected_lesson == 'iframe') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-scorm">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Scorm Content') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-scorm" value="scorm"
|
|
||||||
@if ($selected_lesson == 'scorm') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3">
|
|
||||||
<a href="javascript:void(0)" type="button" class="btn btn-primary" data-toggle="modal"
|
|
||||||
data-dismiss="modal" id="lesson-add-modal" onclick="showLessonAddModal()">{{ get_phrase('Next') }}
|
|
||||||
<i class="fi-rr-angle-small-right"></i> </a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function showLessonAddModal() {
|
|
||||||
var url = $("input[name=lesson_type]:checked").val();
|
|
||||||
ajaxModal('{{ route('modal', ['admin.course.lesson_add', 'id' => $course->id]) }}&lesson_type=' + url,
|
|
||||||
'{{ get_phrase('Add new lesson') }}')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<input type="hidden" name="lesson_type" value="scorm">
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Select scorm provider') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="scorm_provider" required>
|
|
||||||
<option value="">{{ get_phrase('Select a provider') }}</option>
|
|
||||||
<option value="iSpring">{{ get_phrase('iSpring') }}</option>
|
|
||||||
<option value="articulate">{{ get_phrase('Articulate') }}</option>
|
|
||||||
<option value="adobeCaptivate">{{ get_phrase('Adobe Captivate') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Upload scorm file') }}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="custom-file w-100">
|
|
||||||
<input type="file" class="form-control ol-form-control" id="scorm_file" name="scorm_file" accept=".zip"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
initializeDurationPickers([".duration-picker"]);
|
|
||||||
</script>
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<input type="hidden" name="lesson_type" value="scorm">
|
|
||||||
<input type="hidden" name="attachment" value="{{ $lessons->attachment }}">
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Select scorm provider') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="scorm_provider" required>
|
|
||||||
<option value="">{{ get_phrase('Select a provider') }}</option>
|
|
||||||
<option value="iSpring" @if ($lessons->attachment_type == 'iSpring') selected @endif>{{ get_phrase('iSpring') }}</option>
|
|
||||||
<option value="articulate" @if ($lessons->attachment_type == 'articulate') selected @endif>{{ get_phrase('Articulate') }}
|
|
||||||
</option>
|
|
||||||
<option value="adobeCaptivate" @if ($lessons->attachment_type == 'adobeCaptivate') selected @endif>
|
|
||||||
{{ get_phrase('Adobe Captivate') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Update scorm file') }}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="custom-file w-100">
|
|
||||||
<input type="file" class="form-control ol-form-control" id="scorm_file" name="scorm_file" accept=".zip"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
initializeDurationPickers([".duration-picker"]);
|
|
||||||
</script>
|
|
||||||
@ -1,150 +0,0 @@
|
|||||||
<!-- Header -->
|
|
||||||
<div class="ol-header print-d-none d-flex align-items-center justify-content-between py-2 ps-3">
|
|
||||||
<div class="header-title-menubar d-flex align-items-start flex-wrap mt-md-1">
|
|
||||||
<div class="main-header-title d-flex align-items-start pb-sm-0 h-auto p-0">
|
|
||||||
<button class="menu-toggler sidebar-plus">
|
|
||||||
<span class="fi-rr-menu-burger"></span>
|
|
||||||
</button>
|
|
||||||
<h1 class="page-title ms-2 fs-18px d-flex flex-column row-gap-0">
|
|
||||||
<span style="display: -webkit-box !important;
|
|
||||||
-webkit-line-clamp: 1;
|
|
||||||
-webkit-box-orient: vertical !important;
|
|
||||||
overflow: hidden !important;
|
|
||||||
text-overflow: ellipsis !important;
|
|
||||||
white-space: normal !important;">
|
|
||||||
{{ get_settings('system_title') }}
|
|
||||||
</span>
|
|
||||||
<p class="text-12px fw-400 d-none d-lg-none d-xl-inline-block mt-1">{{ get_phrase('Admin Panel') }}</p>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<a href="{{ route('home') }}" target="_blank" class="btn btn-sm p-0 ms-4 ms-md-2 text-14px text-muted">
|
|
||||||
<span>{{ get_phrase('View site') }}</span>
|
|
||||||
<i class="fi-rr-arrow-up-right-from-square text-12px text-muted"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="header-content-right d-flex align-items-center justify-content-end">
|
|
||||||
|
|
||||||
<!-- language Select -->
|
|
||||||
<div class="d-none d-sm-block">
|
|
||||||
<div class="img-text-select ">
|
|
||||||
@php
|
|
||||||
$activated_language = strtolower(session('language') ?? get_settings('language'));
|
|
||||||
@endphp
|
|
||||||
<div class="selected-show" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{ get_phrase('Language') }}">
|
|
||||||
<i class="fi-rr-language text-20px py-2"></i>
|
|
||||||
</div>
|
|
||||||
<div class="drop-content">
|
|
||||||
<ul>
|
|
||||||
@foreach (App\Models\Language::get() as $lng)
|
|
||||||
<li>
|
|
||||||
<a href="{{ route('admin.select.language', ['language' => $lng->name]) }}" class="select-text text-capitalize">
|
|
||||||
|
|
||||||
<i class="fi fi-br-check text-10px me-1 @if ($activated_language != strtolower($lng->name)) visibility-hidden @endif"></i>
|
|
||||||
{{ $lng->name }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a href="#" class="list text-18px d-inline-flex" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight">
|
|
||||||
<span class="d-block h-100 w-100" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{ get_phrase('AI Assistant') }}">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="22" height="22" x="0" y="0" viewBox="0 0 64 64" style="enable-background:new 0 0 512 512" xml:space="preserve" class="">
|
|
||||||
<g>
|
|
||||||
<g fill="#424242">
|
|
||||||
<path d="M36.5 20C27.953 20 21 13.047 21 4.5a.5.5 0 0 0-1 0C20 13.047 13.047 20 4.5 20a.5.5 0 0 0 0 1C13.047 21 20 27.953 20 36.5a.5.5 0 0 0 1 0C21 27.953 27.953 21 36.5 21a.5.5 0 0 0 0-1zM60 34.5a.5.5 0 0 0-.5-.5C52.607 34 47 28.393 47 21.5a.5.5 0 0 0-1 0C46 28.393 40.393 34 33.5 34a.5.5 0 0 0 0 1C40.393 35 46 40.607 46 47.5a.5.5 0 0 0 1 0C47 40.607 52.607 35 59.5 35a.5.5 0 0 0 .5-.5zM38 49.5a.5.5 0 0 0-.5-.5c-5.238 0-9.5-4.262-9.5-9.5a.5.5 0 0 0-1 0c0 5.238-4.262 9.5-9.5 9.5a.5.5 0 0 0 0 1c5.238 0 9.5 4.262 9.5 9.5a.5.5 0 0 0 1 0c0-5.238 4.262-9.5 9.5-9.5a.5.5 0 0 0 .5-.5z" fill="#424242" opacity="1" data-original="#424242" class=""></path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{ get_phrase('Help Center') }}">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<i class="fi-rr-messages-question text-20px"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
|
||||||
<div class="p-2">
|
|
||||||
<h5 class="title text-14px">{{ get_phrase('Help center') }}</h6>
|
|
||||||
</div>
|
|
||||||
<li>
|
|
||||||
<a href="https://creativeitem.com/docs/academy-lms" target="_blank" class="dropdown-item">
|
|
||||||
<i class="fi-rr-document-signed"></i>
|
|
||||||
<span>{{ get_phrase('Read documentation') }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://www.youtube.com/watch?v=-HHhJUGQPeU&list=PLR1GrQCi5Zqvhh7wgtt-ShMAM1RROYJgE" target="_blank" class="dropdown-item">
|
|
||||||
<i class="fi-rr-video-arrow-up-right"></i>
|
|
||||||
<span>{{ get_phrase('Watch video tutorial') }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://support.creativeitem.com" target="_blank" class="dropdown-item">
|
|
||||||
<i class="fi-rr-envelope-plus"></i>
|
|
||||||
<span>{{ get_phrase('Get customer support') }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://support.creativeitem.com" target="_blank" class="dropdown-item">
|
|
||||||
<i class="fi-rr-box-up"></i>
|
|
||||||
<span>{{ get_phrase('Order customization') }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a href="https://support.creativeitem.com" target="_blank" class="select-text text-capitalize">
|
|
||||||
<i class="fi-rr-add"></i>
|
|
||||||
<span>{{ get_phrase('Request a new feature') }}</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://creativeitem.com/services" target="_blank" class="text-premium select-text text-capitalize d-flex align-items-center">
|
|
||||||
<i class="fi-rr-settings-sliders me-1"></i>
|
|
||||||
<span>{{ get_phrase('Get Services') }}</span>
|
|
||||||
<i class="fi-rr-crown ms-auto"></i>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Profile -->
|
|
||||||
<div class="header-dropdown-md">
|
|
||||||
<button class="header-dropdown-toggle-md" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<div class="user-profile-sm">
|
|
||||||
<img src="{{ get_image(auth()->user()->photo) }}" alt="">
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
<div class="header-dropdown-menu-md p-3">
|
|
||||||
<div class="d-flex column-gap-2 mb-12px pb-12px ol-border-bottom-2">
|
|
||||||
<div class="user-profile-sm">
|
|
||||||
<img src="{{ get_image(auth()->user()->photo) }}" alt="">
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h6 class="title fs-12px mb-2px">{{ auth()->user()->name }}</h6>
|
|
||||||
<p class="sub-title fs-12px">{{ ucfirst(auth()->user()->role) }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ul class="mb-12px pb-12px ol-border-bottom-2">
|
|
||||||
<li class="dropdown-list-1"><a class="dropdown-item-1" href="{{ route('admin.manage.profile') }}">{{ get_phrase('My Profile') }}</a></li>
|
|
||||||
@if (has_permission('admin.system.settings'))
|
|
||||||
<li class="dropdown-list-1"><a class="dropdown-item-1" href="{{ route('admin.system.settings') }}">{{ get_phrase('Settings') }}</a></li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li class="dropdown-list-1"><a class="dropdown-item-1" href="{{ route('logout') }}">{{ get_phrase('Sign Out') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
// Date range picker
|
|
||||||
if ($('.daterangepicker:not(.inited)').length) {
|
|
||||||
$('.daterangepicker:not(.inited)').daterangepicker();
|
|
||||||
$('.daterangepicker:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
|
|
||||||
// icon picker
|
|
||||||
if ($('.icon-picker:not(.inited)').length) {
|
|
||||||
$('.icon-picker:not(.inited)').iconpicker();
|
|
||||||
$('.icon-picker:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Select 2
|
|
||||||
if ($('#ajaxModal select.ol-select2:not(.inited)').length) {
|
|
||||||
$('#ajaxModal select.ol-select2:not(.inited)').select2({
|
|
||||||
dropdownParent: $('#ajaxModal')
|
|
||||||
});
|
|
||||||
$('#ajaxModal select.ol-select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
if ($('#right-modal select.ol-select2:not(.inited)').length) {
|
|
||||||
$('#right-modal select.ol-select2:not(.inited)').select2({
|
|
||||||
dropdownParent: $('#right-modal')
|
|
||||||
});
|
|
||||||
$('#right-modal select.ol-select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
if ($('select.ol-select2:not(.inited)').length) {
|
|
||||||
$('select.ol-select2:not(.inited)').select2();
|
|
||||||
$('select.ol-select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($('#ajaxModal select.select2:not(.inited)').length) {
|
|
||||||
$('#ajaxModal select.select2:not(.inited)').select2({
|
|
||||||
dropdownParent: $('#ajaxModal')
|
|
||||||
});
|
|
||||||
$('#ajaxModal select.select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
if ($('#right-modal select.select2:not(.inited)').length) {
|
|
||||||
$('#right-modal select.select2:not(.inited)').select2({
|
|
||||||
dropdownParent: $('#right-modal')
|
|
||||||
});
|
|
||||||
$('#right-modal select.select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
if ($('select.select2:not(.inited)').length) {
|
|
||||||
$('select.select2:not(.inited)').select2();
|
|
||||||
$('select.select2:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
|
|
||||||
//Text editor
|
|
||||||
if ($('.text_editor:not(.inited)').length) {
|
|
||||||
$('.text_editor:not(.inited)').summernote({
|
|
||||||
height: 180, // set editor height
|
|
||||||
minHeight: null, // set minimum height of editor
|
|
||||||
maxHeight: null, // set maximum height of editor
|
|
||||||
focus: true, // set focus to editable area after initializing summernote
|
|
||||||
});
|
|
||||||
$('.text_editor:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
//summary, note_for_student, short_description, message, biography, type-msg, id="comment", summernote, address, website_description
|
|
||||||
|
|
||||||
|
|
||||||
$('.tagify:not(.inited)').each(function(index, element) {
|
|
||||||
var tagify = new Tagify(element, {
|
|
||||||
placeholder: '{{ get_phrase('Enter your keywords') }}',
|
|
||||||
delimiters: "~",
|
|
||||||
});
|
|
||||||
$(element).addClass('inited');
|
|
||||||
});
|
|
||||||
|
|
||||||
var formElement;
|
|
||||||
if ($('.ajaxForm:not(.initialized)').length > 0) {
|
|
||||||
$('.ajaxForm:not(.initialized)').ajaxForm({
|
|
||||||
beforeSend: function(data, form) {
|
|
||||||
var formElement = $(form);
|
|
||||||
},
|
|
||||||
uploadProgress: function(event, position, total, percentComplete) {},
|
|
||||||
complete: function(xhr) {
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
distributeServerResponse(xhr.responseText);
|
|
||||||
}, 400);
|
|
||||||
|
|
||||||
if ($('.ajaxForm.resetable').length > 0) {
|
|
||||||
$('.ajaxForm.resetable')[0].reset();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('.ajaxForm:not(.initialized)').addClass('initialized');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<div class="row mb-3">
|
|
||||||
<label for="email" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Email') }}<span
|
|
||||||
class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="email" name="email" class="form-control ol-form-control" id="email" @isset($instructor->email) value="{{ $instructor->email }}" @endisset required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-8 offset-sm-2">
|
|
||||||
<input type="hidden" name="email_verified" value="0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="email_verified" name="email_verified" value="1">
|
|
||||||
<label class="form-check-label" for="email_verified">{{ get_phrase('Mark email as verified') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if(!isset($instructor->email))
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="password" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Password') }}<span
|
|
||||||
class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="password" name="password" class="form-control ol-form-control" id="password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endisset
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
|
|
||||||
@push('title', get_phrase('Create Instructor'))
|
|
||||||
|
|
||||||
@push('meta')
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@push('css')
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Edit Instructor') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.instructor.index') }}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-arrow-alt-left"></span>
|
|
||||||
<span>{{ get_phrase('Back') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Start Admin area -->
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<h4 class="title fs-16px mb-20px">{{ get_phrase('Instructor Info') }}</h4>
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<form action="{{ route('admin.instructor.update', ['id' => $instructor->id]) }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<div class="d-flex gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<div class="ol-sidebar-tab">
|
|
||||||
<div class="nav flex-column nav-pills" id="myv-pills-tab" role="tablist" aria-orientation="vertical">
|
|
||||||
<button class="nav-link text-start active" id="v-pills-tab1-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tab1" type="button" role="tab"
|
|
||||||
aria-controls="v-pills-tab1" aria-selected="true">
|
|
||||||
<span class="icon fi-rr-duplicate"></span>
|
|
||||||
<span>{{ get_phrase('Basic') }}</span>
|
|
||||||
</button>
|
|
||||||
<button class="nav-link text-start" id="v-pills-tab2-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tab2" type="button" role="tab"
|
|
||||||
aria-controls="v-pills-tab2" aria-selected="false">
|
|
||||||
<span class="fi-rr-key"></span>
|
|
||||||
<span>{{ get_phrase('Login Credentials') }}</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="nav-link text-start" id="v-pills-tab3-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tab3" type="button" role="tab"
|
|
||||||
aria-controls="v-pills-tab3" aria-selected="false">
|
|
||||||
<span class="fi-rr-credit-card"></span>
|
|
||||||
<span>{{ get_phrase('Payment Information') }}</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="nav-link text-start" id="v-pills-tab4-tab" data-bs-toggle="pill" data-bs-target="#v-pills-tab4" type="button" role="tab"
|
|
||||||
aria-controls="v-pills-tab4" aria-selected="false">
|
|
||||||
<span class="fi-rr-link"></span>
|
|
||||||
<span>{{ get_phrase('Social Links') }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-content w-100" id="myv-pills-tabContent">
|
|
||||||
<div class="tab-pane fade show active" id="v-pills-tab1" role="tabpanel" aria-labelledby="v-pills-tab1-tab" tabindex="0">
|
|
||||||
<div class="dashboard-tab-conTent">
|
|
||||||
@include('admin.instructor.edit_instructor_basic')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="v-pills-tab2" role="tabpanel" aria-labelledby="v-pills-tab2-tab" tabindex="0">
|
|
||||||
<div class="dashboard-tab-conTent">
|
|
||||||
@include('admin.instructor.edit_login')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="v-pills-tab3" role="tabpanel" aria-labelledby="v-pills-tab3-tab" tabindex="0">
|
|
||||||
<div class="dashboard-tab-conTent">
|
|
||||||
@include('admin.instructor.edit_payment')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="v-pills-tab4" role="tabpanel" aria-labelledby="v-pills-tab4-tab" tabindex="0">
|
|
||||||
<div class="dashboard-tab-conTent">
|
|
||||||
@include('admin.instructor.edit_social')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn ol-btn-primary mt-3">
|
|
||||||
<span>{{ get_phrase('Update Instructor') }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- End Admin area -->
|
|
||||||
@endsection
|
|
||||||
@ -1,158 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
|
|
||||||
@push('title', get_phrase('Instructor'))
|
|
||||||
|
|
||||||
@push('meta')
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@push('css')
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Instructor List') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.instructor.create') }}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add new Instructor') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
|
|
||||||
<div class="row print-d-none mb-3 mt-3 row-gap-3">
|
|
||||||
<div class="col-md-6 pt-2 pt-md-0">
|
|
||||||
<div class="custom-dropdown">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="downloadPDF('.print-table', 'instructor-list')"><i class="fi-rr-file-pdf"></i> {{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<form class="form-inline" action="{{ route('admin.instructor.index') }}" method="get">
|
|
||||||
<div class="row row-gap-3">
|
|
||||||
<div class="col-md-9">
|
|
||||||
<input type="text" class="form-control ol-form-control" name="search" value="{{ request('search') }}" placeholder="{{ get_phrase('Search user') }}" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<button type="submit" class="btn ol-btn-primary w-100" id="submit-button"> {{ get_phrase('Search') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-4">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<!-- Table -->
|
|
||||||
@if (count($instructors) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($instructors) . ' ' . get_phrase('of') . ' ' . $instructors->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive course_list" id="course_list">
|
|
||||||
<table class="table eTable eTable-2 print-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('Name') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Phone') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Number Of Course') }}</th>
|
|
||||||
<th class="print-d-none" scope="col">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($instructors as $key => $row)
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ ++$key }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_img">
|
|
||||||
<img class="img-fluid rounded-circle image-45" width="45" height="45" src="{{ get_image($row->photo) }}" />
|
|
||||||
</div>
|
|
||||||
<div class="ms-1">
|
|
||||||
<h4 class="title fs-14px">{{ $row->name }}</h4>
|
|
||||||
<p class="sub-title2 text-12px">{{ $row->email }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name min-w-150px">
|
|
||||||
<p>{{ $row->phone }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ App\Models\Course::where('user_id', $row->id)->count() }}
|
|
||||||
{{ get_phrase('Courses') }}
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ route('admin.courses', ['instructor' => $row->id]) }}">{{ get_phrase('View courses') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ route('admin.instructor.edit', $row->id) }}">{{ get_phrase('Edit') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.instructor.delete', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Remove account') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.instructor.revoke_access', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Revoke Instructor Access') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
<!-- Data info and Pagination -->
|
|
||||||
@if (count($instructors) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($instructors) . ' ' . get_phrase('of') . ' ' . $instructors->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $instructors->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
@endpush
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
<form action="{{ route('admin.knowledge.base.store') }}" method="post">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="title" class="form-label ol-form-label">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" id="title" placeholder="{{ get_phrase('Subject') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Submit') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
@php
|
|
||||||
$data = App\Models\Knowledge_base::where('id', $id)->first();
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<form action="{{ route('admin.knowledge.base.update', $id) }}" method="post">@csrf
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="title" class="form-label ol-form-label">{{ get_phrase('title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" id="title" value="{{ $data->title }}" placeholder="{{ get_phrase('Title') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{-- <div class="mb-3">
|
|
||||||
<label for="title" class="form-label ol-form-label">{{ get_phrase('Description') }}</label>
|
|
||||||
<textarea name="title" id="title" required>{{ $data->title }}</textarea>
|
|
||||||
</div> --}}
|
|
||||||
|
|
||||||
<div class="fpb-7">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Submit') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{-- <script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$('#title').summernote({
|
|
||||||
height: 180, // set editor height
|
|
||||||
minHeight: null, // set minimum height of editor
|
|
||||||
maxHeight: null, // set maximum height of editor
|
|
||||||
focus: true, // set focus to editable area after initializing summernote
|
|
||||||
toolbar: [
|
|
||||||
['color', ['color']],
|
|
||||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
|
||||||
['fontsize', ['fontsize']],
|
|
||||||
['para', ['ul', 'ol']],
|
|
||||||
['table', ['table']],
|
|
||||||
['insert', ['link']]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
</script> --}}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Knowledge_base'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Knowledge base') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a onclick="ajaxModal('{{ route('modal', ['admin.knowledge_base.create']) }}', '{{ get_phrase('Add knowledge base') }}')" href="#" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add Knowledge base') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 ">
|
|
||||||
<div id="accordion" class="custom-accordion mb-4">
|
|
||||||
<div class="ol-card p-20px">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<ul class="ol-my-accordion">
|
|
||||||
@if (count($datas) > 0)
|
|
||||||
<div class="table-responsive course_list overflow-auto overflow-auto " id="course_list ">
|
|
||||||
<table class="eTable eTable-2 print-table table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('Title') }}</th>
|
|
||||||
<th scope="col" class="print-d-none text-center">{{ get_phrase('Total Articles') }}</th>
|
|
||||||
<th scope="col" class="print-d-none text-center">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($datas as $key => $data)
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ ++$key }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
<h4 class="title fs-14px">
|
|
||||||
<a href="#">{{ ucfirst($data->title) }}</a>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="print-d-none text-center">
|
|
||||||
@php
|
|
||||||
$total = App\Models\Knowledge_base_topick::where('knowledge_base_id', $data->id)->get();
|
|
||||||
@endphp
|
|
||||||
{{count($total)}}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="print-d-none ">
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent d-flex justify-content-center">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{route('admin.articles', ['id' => $data->id])}}">{{ get_phrase(' Articles') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a onclick="ajaxModal('{{ route('modal', ['admin.knowledge_base.edit', 'id' => $data->id]) }}', '{{ get_phrase('Edit Newsletter') }}')" data-bs-toggle="tooltip" title="{{ get_phrase('Edit') }}" href="#">{{ get_phrase('Edit') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.knowledge.base.delete', $data->id) }}')" href="javascript:void(0)">{{ get_phrase('Delete') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (count($datas) > 0)
|
|
||||||
<div
|
|
||||||
class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($datas) . ' ' . get_phrase('of') . ' ' . $datas->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $datas->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function stopProp(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,586 +0,0 @@
|
|||||||
@php $current_route = Route::currentRouteName(); @endphp
|
|
||||||
|
|
||||||
<div class="sidebar-logo-area">
|
|
||||||
<a href="#" class="sidebar-logos">
|
|
||||||
<img class="sidebar-logo-lg" height="50px" src="{{ get_image(get_frontend_settings('dark_logo')) }}"
|
|
||||||
alt="">
|
|
||||||
<img class="sidebar-logo-sm" height="40px" src="{{ get_image(get_frontend_settings('favicon')) }}" alt="">
|
|
||||||
</a>
|
|
||||||
<button class="sidebar-cross menu-toggler d-block d-lg-none">
|
|
||||||
<span class="fi-rr-cross"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<h3 class="sidebar-title fs-12px px-30px pb-20px text-uppercase mt-4">{{ get_phrase('Main Menu') }}</h3>
|
|
||||||
<div class="sidebar-nav-area">
|
|
||||||
<nav class="sidebar-nav">
|
|
||||||
<ul class="px-14px pb-24px">
|
|
||||||
|
|
||||||
@if (has_permission('admin.dashboard'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.dashboard' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.dashboard') }}">
|
|
||||||
<span class="icon fi-rr-house-blank"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Dashboard') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
@if (has_permission('admin.categories'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.categories' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.categories') }}">
|
|
||||||
<span class="icon fi-rr-chart-tree-map"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Category') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
@if (has_permission('admin.courses'))
|
|
||||||
<li class="sidebar-first-li first-li-have-sub @if (
|
|
||||||
$current_route == 'admin.courses' ||
|
|
||||||
$current_route == 'admin.course.create' ||
|
|
||||||
$current_route == 'admin.course.edit' ||
|
|
||||||
$current_route == 'admin.coupons') active showMenu @endif">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-e-learning"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Course') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Course') }}</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.courses' || $current_route == 'admin.course.edit') active @endif">
|
|
||||||
<a href="{{ route('admin.courses') }}">{{ get_phrase('Manage Courses') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.course.create') active @endif">
|
|
||||||
<a href="{{ route('admin.course.create') }}">{{ get_phrase('Add New Course') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.coupons') active @endif">
|
|
||||||
<a href="{{ route('admin.coupons') }}">{{ get_phrase('Coupons') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.bootcamps'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.bootcamps' || $current_route == 'admin.bootcamp.create' || $current_route == 'admin.bootcamp.edit' || $current_route == 'admin.bootcamp.purchase.history' || $current_route == 'admin.bootcamp.purchase.invoice' || $current_route == 'admin.bootcamp.categories' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-sr-users-alt"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Bootcamp') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Bootcamp') }}</li>
|
|
||||||
|
|
||||||
<li class="sidebar-second-li @if (($current_route == 'admin.bootcamps' || $current_route == 'admin.bootcamp.edit') && request('type') == '') active @endif"><a
|
|
||||||
href="{{ route('admin.bootcamps') }}">{{ get_phrase('Manage Bootcamps') }}</a></li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.bootcamp.create') active @endif">
|
|
||||||
<a href="{{ route('admin.bootcamp.create') }}">{{ get_phrase('Add New Bootcamp') }}</a>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.bootcamp.purchase.history' || $current_route == 'admin.bootcamp.purchase.invoice' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.bootcamp.purchase.history') }}">{{ get_phrase('Purchase History') }}</a>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.bootcamp.categories' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.bootcamp.categories') }}">{{ get_phrase('Category') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
{{-- @if (has_permission('admin.team.packages'))
|
|
||||||
<li class="sidebar-first-li first-li-have-sub @if ($current_route == 'admin.team.packages' || $current_route == 'admin.team.packages.create' || $current_route == 'admin.team.packages.edit' || $current_route == 'admin.team.packages.purchase.history' || $current_route == 'admin.team.packages.purchase.invoice') active showMenu @endif">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-document-signed"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Team Training') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Team Training') }}</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.team.packages' || $current_route == 'admin.team.packages.edit') active @endif">
|
|
||||||
<a href="{{ route('admin.team.packages') }}">{{ get_phrase('Manage Packages') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.team.packages.create') active @endif">
|
|
||||||
<a href="{{ route('admin.team.packages.create') }}">{{ get_phrase('Add New Package') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.team.packages.purchase.history' || $current_route == 'admin.team.packages.purchase.invoice' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.team.packages.purchase.history') }}">{{ get_phrase('Purchase History') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif --}}
|
|
||||||
|
|
||||||
@if (has_permission('admin.tutor_categories'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub @if ($current_route == 'admin.tutor_subjects' || $current_route == 'admin.tutor_categories') active showMenu @endif">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-document-signed"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Tutor Booking') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Tutor Booking') }}</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.tutor_subjects') active @endif">
|
|
||||||
<a href="{{ route('admin.tutor_subjects') }}">{{ get_phrase('Subjects') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li @if ($current_route == 'admin.tutor_categories') active @endif">
|
|
||||||
<a href="{{ route('admin.tutor_categories') }}">{{ get_phrase('Subject Category') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.enroll.history') || has_permission('admin.student.enroll'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.student.enroll' || $current_route == 'admin.enroll.history' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi-rr-elevator"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Student enrollment') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Course enrollment') }}</li>
|
|
||||||
|
|
||||||
@if (has_permission('admin.enroll.history'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.enroll.history' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.enroll.history') }}">{{ get_phrase('Enrollment History') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.student.enroll'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.student.enroll' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.student.enroll') }}">{{ get_phrase('Enroll student') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
@if (has_permission('admin.offline.payments') ||
|
|
||||||
has_permission('admin.revenue') ||
|
|
||||||
has_permission('admin.instructor.revenue') ||
|
|
||||||
has_permission('admin.purchase.history'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.offline.payments' || $current_route == 'admin.revenue' || $current_route == 'admin.instructor.revenue' || $current_route == 'admin.purchase.history' || $current_route == 'admin.purchase.history.invoice' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi-rr-comment-dollar"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Payment Report') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Payment Report') }}</li>
|
|
||||||
|
|
||||||
@if (has_permission('admin.offline.payments'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.offline.payments' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.offline.payments') }}">{{ get_phrase('Offline payments') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.revenue'))
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.revenue' ? 'active' : '' }}"><a
|
|
||||||
href="{{ route('admin.revenue') }}">{{ get_phrase('Admin Revenue') }}</a></li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.instructor.revenue'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.instructor.revenue' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.revenue') }}">{{ get_phrase('Instructor Revenue') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.purchase.history'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.purchase.history' || $current_route == 'admin.purchase.history.invoice' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.purchase.history') }}">{{ get_phrase('Payment History') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.admins.index') ||
|
|
||||||
has_permission('admin.instructor.index') ||
|
|
||||||
has_permission('admin.student.index'))
|
|
||||||
<li class="sidebar-first-li first-li-have-sub @if (
|
|
||||||
$current_route == 'admin.instructor.index' ||
|
|
||||||
$current_route == 'admin.instructor.create' ||
|
|
||||||
$current_route == 'admin.instructor.edit' ||
|
|
||||||
$current_route == 'admin.instructor.payout' ||
|
|
||||||
$current_route == 'admin.instructor.payout.filter' ||
|
|
||||||
$current_route == 'admin.instructor.setting' ||
|
|
||||||
$current_route == 'admin.instructor.application' ||
|
|
||||||
$current_route == 'admin.admins.index' ||
|
|
||||||
$current_route == 'admin.admins.create' ||
|
|
||||||
$current_route == 'admin.admins.edit' ||
|
|
||||||
$current_route == 'admin.admins.permission' ||
|
|
||||||
$current_route == 'admin.student.index' ||
|
|
||||||
$current_route == 'admin.student.edit' ||
|
|
||||||
$current_route == 'admin.student.create') active @endif">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi-rr-users"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Users') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Users') }}</li>
|
|
||||||
@if (has_permission('admin.admins.index'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li second-li-have-sub @if (
|
|
||||||
$current_route == 'admin.admins.index' ||
|
|
||||||
$current_route == 'admin.admins.create' ||
|
|
||||||
$current_route == 'admin.admins.edit' ||
|
|
||||||
$current_route == 'admin.admins.permission') active @endif">
|
|
||||||
<a href="javascript:void(0);">{{ get_phrase('Admin') }}</a>
|
|
||||||
<ul class="second-sub-menu">
|
|
||||||
<li class="sidebar-third-li @if (
|
|
||||||
$current_route == 'admin.admins.index' ||
|
|
||||||
$current_route == 'admin.admins.permission' ||
|
|
||||||
$current_route == 'admin.admins.edit') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.admins.index') }}">{{ get_phrase('Manage Admin') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.admins.create') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.admins.create') }}">{{ get_phrase('Add New Admin') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.instructor.index'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li second-li-have-sub @if (
|
|
||||||
$current_route == 'admin.instructor.index' ||
|
|
||||||
$current_route == 'admin.instructor.create' ||
|
|
||||||
$current_route == 'admin.instructor.edit' ||
|
|
||||||
$current_route == 'admin.instructor.payout' ||
|
|
||||||
$current_route == 'admin.instructor.payout.filter' ||
|
|
||||||
$current_route == 'admin.instructor.setting' ||
|
|
||||||
$current_route == 'admin.instructor.application') active @endif">
|
|
||||||
<a href="javascript:void(0);">{{ get_phrase('Instructor') }}</a>
|
|
||||||
<ul class="second-sub-menu">
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.instructor.index' || $current_route == 'admin.instructor.edit') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.index') }}">{{ get_phrase('Manage Instructors') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.instructor.create') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.create') }}">{{ get_phrase('Add new Instructor') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.instructor.payout' || $current_route == 'admin.instructor.payout.filter') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.payout') }}">{{ get_phrase('Instructor Payout') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.instructor.setting') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.setting') }}">{{ get_phrase('Instructor Setting') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.instructor.application') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.instructor.application') }}">{{ get_phrase('Application') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.student.index'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li second-li-have-sub @if (
|
|
||||||
$current_route == 'admin.student.index' ||
|
|
||||||
$current_route == 'admin.student.edit' ||
|
|
||||||
$current_route == 'admin.student.create') active @endif">
|
|
||||||
<a href="javascript:void(0);">{{ get_phrase('Student') }}</a>
|
|
||||||
<ul class="second-sub-menu">
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.student.index' || $current_route == 'admin.student.edit') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.student.index') }}">{{ get_phrase('Manage Students') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-third-li @if ($current_route == 'admin.student.create') active @endif">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.student.create') }}">{{ get_phrase('Add new Student') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.message'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.message' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.message') }}">
|
|
||||||
<span class="icon fi-rr-messages"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Message') }}</span>
|
|
||||||
</div>
|
|
||||||
@if (
|
|
||||||
$unread_msg =
|
|
||||||
App\Models\Message::where('receiver_id', auth()->user()->id)->where('read', '')->count() > 0)
|
|
||||||
<span class="d-inline-block mt-2px badge bg-danger ms-auto">{{ $unread_msg }}</span>
|
|
||||||
@endif
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.newsletter'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.newsletter' || $current_route == 'admin.subscribed_user' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-envelope-open-text"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Newsletter') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Newsletter') }}</li>
|
|
||||||
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.newsletter' ? 'active' : '' }}"><a
|
|
||||||
href="{{ route('admin.newsletter') }}">{{ get_phrase('Manage Newsletters') }}</a>
|
|
||||||
</li>
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.subscribed_user' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.subscribed_user') }}">{{ get_phrase('Subscribed User') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.contacts'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.contacts' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.contacts') }}">
|
|
||||||
<span class="icon fi fi-br-portrait"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Contacts') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.blogs') ||
|
|
||||||
has_permission('admin.blog.pending') ||
|
|
||||||
has_permission('admin.blog.category') ||
|
|
||||||
has_permission('admin.blog.category'))
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.blogs' || $current_route == 'admin.blog.create' || $current_route == 'admin.blog.edit' || $current_route == 'admin.blog.pending' || $current_route == 'admin.blog.category' || $current_route == 'admin.blog.settings' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-blog-text"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Blogs') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('Blogs') }}</li>
|
|
||||||
@if (has_permission('admin.blogs'))
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.blogs' ? 'active' : '' }}"><a
|
|
||||||
href="{{ route('admin.blogs') }}">{{ get_phrase('Manage Blogs') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.blog.pending'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.blog.pending' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.blog.pending') }}">{{ get_phrase('Pending Blogs') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.blog.category'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.blog.category' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.blog.category') }}">{{ get_phrase('Category') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.blog.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.blog.settings' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.blog.settings') }}">{{ get_phrase('Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (has_permission('admin.knowledge.base'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.knowledge.base' || $current_route == 'admin.articles' || $current_route == 'admin.articles.create' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.knowledge.base') }}">
|
|
||||||
<span class="icon fi-rr-brain"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Knowledge Base') }}</span>
|
|
||||||
</div>
|
|
||||||
@if (
|
|
||||||
$unread_msg =
|
|
||||||
App\Models\Message::where('receiver_id', auth()->user()->id)->where('read', '')->count() > 0)
|
|
||||||
<span class="d-inline-block mt-2px badge bg-danger ms-auto">{{ $unread_msg }}</span>
|
|
||||||
@endif
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@if (has_permission('admin.system.settings') ||
|
|
||||||
has_permission('admin.website.settings') ||
|
|
||||||
has_permission('admin.payment.settings') ||
|
|
||||||
has_permission('admin.manage.language') ||
|
|
||||||
has_permission('admin.notification.settings') ||
|
|
||||||
has_permission('admin.live.class.settings') ||
|
|
||||||
has_permission('admin.certificate.settings') ||
|
|
||||||
has_permission('admin.player.settings') ||
|
|
||||||
has_permission('admin.open.ai.settings') ||
|
|
||||||
has_permission('admin.pages') ||
|
|
||||||
has_permission('admin.seo.settings') ||
|
|
||||||
has_permission('admin.about'))
|
|
||||||
<nav class="sidebar-nav">
|
|
||||||
<h3 class="sidebar-title fs-12px px-30px text-uppercase pb-3">{{ get_phrase('Settings') }}</h3>
|
|
||||||
<ul class="px-14px pb-24px mb-5 pb-5">
|
|
||||||
<li
|
|
||||||
class="sidebar-first-li first-li-have-sub {{ $current_route == 'admin.system.settings' || $current_route == 'admin.website.settings' || $current_route == 'admin.language.phrase.edit' || $current_route == 'admin.payment.settings' || $current_route == 'admin.manage.language' || $current_route == 'admin.notification.settings' || $current_route == 'admin.live.class.settings' || $current_route == 'admin.live.class.settings' || $current_route == 'admin.certificate.settings' || $current_route == 'admin.player.settings' || $current_route == 'admin.open.ai.settings' || $current_route == 'admin.pages' || $current_route == 'admin.seo.settings' || $current_route == 'admin.about' ? 'active' : '' }}">
|
|
||||||
<a href="javascript:void(0);">
|
|
||||||
<span class="icon fi fi-rr-settings"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('System Settings') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
<ul class="first-sub-menu">
|
|
||||||
<li class="first-sub-menu-title fs-14px mb-18px">{{ get_phrase('System Settings') }}</li>
|
|
||||||
@if (has_permission('admin.system.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.system.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.system.settings') }}">{{ get_phrase('System Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.website.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.website.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.website.settings') }}">{{ get_phrase('Website Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.payment.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.payment.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.payment.settings') }}">{{ get_phrase('Payment Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.manage.language'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.manage.language' || $current_route == 'admin.language.phrase.edit' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.manage.language') }}">{{ get_phrase('Manage Language') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.live.class.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.live.class.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.live.class.settings') }}">{{ get_phrase('Live Class Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.notification.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.notification.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.notification.settings') }}">{{ get_phrase('SMTP Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.certificate.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.certificate.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.certificate.settings') }}">{{ get_phrase('Certificate Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.player.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.player.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.player.settings') }}">{{ get_phrase('Player Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.open.ai.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.open.ai.settings' ? 'active' : '' }}">
|
|
||||||
<a
|
|
||||||
href="{{ route('admin.open.ai.settings') }}">{{ get_phrase('Open AI Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.pages'))
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.pages' ? 'active' : '' }}"><a
|
|
||||||
href="{{ route('admin.pages') }}">{{ get_phrase('Home Page Builder') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.seo.settings'))
|
|
||||||
<li
|
|
||||||
class="sidebar-second-li {{ $current_route == 'admin.seo.settings' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.seo.settings') }}">{{ get_phrase('SEO Settings') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if (has_permission('admin.about'))
|
|
||||||
<li class="sidebar-second-li {{ $current_route == 'admin.about' ? 'active' : '' }}"><a
|
|
||||||
href="{{ route('admin.about') }}">{{ get_phrase('About') }}</a></li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
@if (has_permission('admin.manage.profile'))
|
|
||||||
<li class="sidebar-first-li {{ $current_route == 'admin.manage.profile' ? 'active' : '' }}">
|
|
||||||
<a href="{{ route('admin.manage.profile') }}">
|
|
||||||
<span class="icon fi-rr-circle-user"></span>
|
|
||||||
<div class="text">
|
|
||||||
<span>{{ get_phrase('Manage Profile') }}</span>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
// Restore scroll position if it exists in localStorage
|
|
||||||
const scrollPos = localStorage.getItem('navScrollPos');
|
|
||||||
const sidebarNavArea = document.querySelector('.sidebar-nav-area');
|
|
||||||
if (scrollPos) {
|
|
||||||
sidebarNavArea.scrollTop = scrollPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure the active element is visible
|
|
||||||
const activeElement = document.querySelector('.sidebar-nav-area .active');
|
|
||||||
if (activeElement) {
|
|
||||||
const activeElementTop = activeElement.getBoundingClientRect().top;
|
|
||||||
const navAreaTop = sidebarNavArea.getBoundingClientRect().top;
|
|
||||||
const navAreaBottom = navAreaTop + sidebarNavArea.clientHeight;
|
|
||||||
|
|
||||||
if (activeElementTop < navAreaTop || activeElementTop > navAreaBottom) {
|
|
||||||
sidebarNavArea.scrollTop = activeElement.offsetTop - sidebarNavArea.offsetTop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save scroll position before page unload
|
|
||||||
window.addEventListener('beforeunload', function() {
|
|
||||||
localStorage.setItem('navScrollPos', sidebarNavArea.scrollTop);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,236 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Offline payments'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<!-- Mani section header and breadcrumb -->
|
|
||||||
<div class="ol-card radius-8px print-d-none">
|
|
||||||
<div class="ol-card-body px-20px my-3 py-4">
|
|
||||||
<div class="d-flex align-items-center justify-content-between flex-md-nowrap flex-wrap gap-3">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
<span>{{ get_phrase('Offline payments') }}</span>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="ol-card">
|
|
||||||
<div class="ol-card-body p-3">
|
|
||||||
<div class="row print-d-none row-gap-3 mb-3 mt-3">
|
|
||||||
<div class="col-md-6 d-flex align-items-center gap-3">
|
|
||||||
<div class="custom-dropdown">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="downloadPDF('.print-table', 'offline-payments')"><i class="fi-rr-file-pdf"></i>
|
|
||||||
{{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="custom-dropdown dropdown-filter @if (!isset($_GET) || (isset($_GET) && count($_GET) == 0)) @endif">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
<i class="fi-rr-filter me-2"></i>
|
|
||||||
{{ get_phrase('Filter') }}
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET))
|
|
||||||
<span class="text-12px">
|
|
||||||
({{ count($_GET) }})
|
|
||||||
</span>
|
|
||||||
@endif
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list w-250px">
|
|
||||||
<li>
|
|
||||||
<form id="filter-dropdown" action="{{ route('admin.offline.payments') }}" method="get">
|
|
||||||
<div class="filter-option d-flex flex-column gap-3">
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Category') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="status" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}</option>
|
|
||||||
<option value="pending" @if (isset($_GET['status']) && $_GET['status'] == 'pending') selected @endif>{{ get_phrase('Pending') }}</option>
|
|
||||||
<option value="approved" @if (isset($_GET['status']) && $_GET['status'] == 'approved') selected @endif>{{ get_phrase('Approved') }}</option>
|
|
||||||
<option value="suspended" @if (isset($_GET['status']) && $_GET['status'] == 'suspended') selected @endif>{{ get_phrase('Suspended') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button d-flex justify-content-end align-items-center mt-3">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Apply') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET) > 0)
|
|
||||||
<a href="{{ route('admin.offline.payments') }}" class="me-2" data-bs-toggle="tooltip" title="{{ get_phrase('Clear') }}"><iclass="fi-rr-cross-circle"></iclass=></a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Table -->
|
|
||||||
@if (count($payments) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center gr-15 flex-wrap">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($payments) . ' ' . get_phrase('of') . ' ' . $payments->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive course_list" id="course_list">
|
|
||||||
<table class="eTable eTable-2 print-table table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('User') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Items') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Type') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Total') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Issue date') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Payment info') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Status') }}</th>
|
|
||||||
<th scope="col" class="print-d-none">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($payments as $key => $payment)
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ $key + 1 }}</p>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
<h4 class="title fs-14px">
|
|
||||||
{{ get_user_info($payment->user_id)->name }}
|
|
||||||
</h4>
|
|
||||||
<p class="sub-title text-12px">{{ get_user_info($payment->user_id)->email }}</p>
|
|
||||||
<p class="sub-title text-12px">{{get_phrase('Phone')}}: {{ get_user_info($payment->user_id)->phone }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
@if ($payment->item_type == 'course')
|
|
||||||
@foreach (App\Models\Course::whereIn('id', json_decode($payment->items, true))->get() as $course)
|
|
||||||
<p class="sub-title text-12px">
|
|
||||||
<a href="{{ route('course.details', slugify($course->title)) }}" class="text-muted me-3">{{ $course->title }} </a>
|
|
||||||
</p>
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($payment->item_type == 'bootcamp')
|
|
||||||
@foreach (App\Models\Bootcamp::whereIn('id', json_decode($payment->items, true))->get() as $bootcamp)
|
|
||||||
<p class="sub-title text-12px">
|
|
||||||
<a href="{{ route('bootcamp.details', ['slug' => slugify($bootcamp->title)]) }}" class="text-muted me-3">{{ $bootcamp->title }} </a>
|
|
||||||
</p>
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($payment->item_type == 'package')
|
|
||||||
@foreach (App\Models\TeamTrainingPackage::whereIn('id', json_decode($payment->items, true))->get() as $package)
|
|
||||||
<p class="sub-title text-12px">
|
|
||||||
<a href="{{ route('team.package.details', ['slug' => $package->slug]) }}" class="text-muted me-3">{{ $package->title }} </a>
|
|
||||||
</p>
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if ($payment->item_type == 'tutor_booking')
|
|
||||||
@foreach (App\Models\TutorSchedule::whereIn('id', json_decode($payment->items, true))->get() as $tutor_schedule)
|
|
||||||
<p class="sub-title text-12px">
|
|
||||||
{{ $tutor_schedule->schedule_to_tutorSubjects->name }}
|
|
||||||
</p>
|
|
||||||
<small><a href="{{ route('tutor_schedule', [$tutor_schedule->tutor_id, slugify($tutor_schedule->schedule_to_tutor->name)]) }}" target="_blank" class="text-muted me-3">{{ $tutor_schedule->schedule_to_tutor->name }} </a></small>
|
|
||||||
@endforeach
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<span class="badge bg-info">{{ ucfirst($payment->item_type) }}</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
{{ currency($payment->total_amount) }}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<p>{{ date('d-M-y', strtotime($payment->created_at)) }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<a class="dropdown-item btn ol-btn-primary px-2 py-1" href="{{ route('admin.offline.payment.doc', $payment->id) }}"><i class="fi-rr-cloud-download"></i> {{ get_phrase('Download') }}</a>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
@if ($payment->status == 1)
|
|
||||||
<span class="badge bg-success">{{ get_phrase('Accepted') }}</span>
|
|
||||||
@elseif($payment->status == 2)
|
|
||||||
<span class="badge bg-danger">{{ get_phrase('Suspended') }}</span>
|
|
||||||
@else
|
|
||||||
<span class="badge bg-warning">{{ get_phrase('Pending') }}</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td class="print-d-none">
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li><a class="dropdown-item" href="{{ route('admin.offline.payment.doc', $payment->id) }}">{{ get_phrase('Download') }}</a>
|
|
||||||
</li>
|
|
||||||
@if ($payment->status != 1)
|
|
||||||
<li><a class="dropdown-item" href="{{ route('admin.offline.payment.accept', $payment->id) }}">{{ get_phrase('Accept') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
@if ($payment->status != 2 && $payment->status != 1)
|
|
||||||
<li><a class="dropdown-item" href="#" onclick="confirmModal('{{ route('admin.offline.payment.decline', $payment->id) }}')">{{ get_phrase('Decline') }}</a>
|
|
||||||
</li>
|
|
||||||
@endif
|
|
||||||
<li><a class="dropdown-item" href="#" onclick="confirmModal('{{ route('admin.offline.payment.delete', $payment->id) }}')">{{ get_phrase('Delete') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
<!-- Data info and Pagination -->
|
|
||||||
@if (count($payments) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center gr-15 flex-wrap">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($payments) . ' ' . get_phrase('of') . ' ' . $payments->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $payments->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection()
|
|
||||||
@ -1,169 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Admin Revenue'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-4 px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Admin Revenue') }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<div class="row mb-3 mt-3 row-gap-3">
|
|
||||||
<div class="col-md-6 pt-2 pt-md-0">
|
|
||||||
@if ($reports->count() > 0)
|
|
||||||
<div class="custom-dropdown">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="downloadPDF('.print-table', 'admin-revenue')"><i class="fi-rr-file-pdf"></i> {{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<form class="form-inline" action="{{ route('admin.revenue') }}" method="get">
|
|
||||||
<div class="row row-gap-3">
|
|
||||||
<div class="col-md-9">
|
|
||||||
<div class="mb-3 position-relative position-relative">
|
|
||||||
<input type="text" class="form-control ol-form-control daterangepicker w-100" name="eDateRange"value="{{ date('m/d/Y', $start_date) . ' - ' . date('m/d/Y', $end_date) }}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<button type="submit" class="btn ol-btn-primary w-100" id="submit-button" onclick="update_date_range();"> {{ get_phrase('Filter') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-4">
|
|
||||||
<div class="col-md-12">
|
|
||||||
@if ($reports->count() > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($reports) . ' ' . get_phrase('of') . ' ' . $reports->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive enroll_history" id="enroll_history">
|
|
||||||
<table class="table eTable eTable-2 print-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ get_phrase('#') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Enrolled course') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Total amount') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Admin revenue') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Enrolled') }}</th>
|
|
||||||
<th scope="col" class="print-d-none">{{ get_phrase('Option') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($reports as $key => $report)
|
|
||||||
@php
|
|
||||||
if ($report->course_id > 0) {
|
|
||||||
$item = App\Models\Course::where('id', $report->course_id)->firstOrNew();
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ $key + 1 }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
<h4 class="title fs-14px">{{ $item->title }}</h4>
|
|
||||||
<p class="mt-1 fs-12px">{{ get_phrase('Enrolled: ') }}
|
|
||||||
{{ date('d-M-Y', strtotime($report->created_at)) }}</p>
|
|
||||||
@isset($report->coupon)
|
|
||||||
<p>{{ get_phrase('Coupon: ') }}{{ $report->coupon }}</p>
|
|
||||||
@endisset
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name">
|
|
||||||
<p>{{ currency($report->amount) }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name">
|
|
||||||
<p>{{ currency($report->admin_revenue) }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name">
|
|
||||||
<p>{{ date('d-M-Y', strtotime($report->created_at)) }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
<div class="adminTable-action">
|
|
||||||
<button type="button" class="btn ol-btn-light ol-icon-btn" data-bs-toggle="tooltip" title="{{ get_phrase('Delete') }}" onclick="confirmModal('{{ route('admin.revenue.delete', $report->id) }}')">
|
|
||||||
<i class="fi-rr-trash"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
<tr>
|
|
||||||
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
<th>{{ get_phrase('Total') }} :
|
|
||||||
{{ currency($reports->sum('amount')) }}
|
|
||||||
</th>
|
|
||||||
<th>{{ get_phrase('Total') }} :
|
|
||||||
{{ currency($reports->sum('admin_revenue')) }}
|
|
||||||
</th>
|
|
||||||
<th></th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
<!-- Data info and Pagination -->
|
|
||||||
@if (count($reports) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($reports) . ' ' . get_phrase('of') . ' ' . $reports->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $reports->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function update_date_range() {
|
|
||||||
var x = $("#selectedValue").html();
|
|
||||||
$("#date_range").val(x);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Multi language setting'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-4 px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Manage Language') }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<p class="title text-14px mb-3">{{ get_phrase('Manage Language') }}</p>
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<ul class="nav nav-tabs eNav-Tabs-custom eTab" id="myTab" role="tablist">
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link active" id="cHome-tab" data-bs-toggle="tab" data-bs-target="#cHome" type="button" role="tab" aria-controls="cHome" aria-selected="true">
|
|
||||||
{{ get_phrase('Language list') }}
|
|
||||||
<span></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="cProfile-tab" data-bs-toggle="tab" data-bs-target="#cProfile" type="button" role="tab" aria-controls="cProfile" aria-selected="false">
|
|
||||||
{{ get_phrase('Add Language') }}
|
|
||||||
<span></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" id="cMessage-tab" data-bs-toggle="tab" data-bs-target="#cMessage" type="button" role="tab" aria-controls="cMessage" aria-selected="false">
|
|
||||||
{{ get_phrase('Import Language') }}
|
|
||||||
<span></span>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="tab-content eNav-Tabs-content" id="myTabContent">
|
|
||||||
<div class="tab-pane fade show active" id="cHome" role="tabpanel" aria-labelledby="cHome-tab">
|
|
||||||
<!----TABLE LISTING STARTS-->
|
|
||||||
<div class="tab-pane show active" id="list">
|
|
||||||
|
|
||||||
<div class="table-responsive">
|
|
||||||
<table class="table mt-3">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">{{ get_phrase('Language') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Direction') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Option') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@php
|
|
||||||
$languages = App\Models\Language::get();
|
|
||||||
@endphp
|
|
||||||
@foreach ($languages as $language)
|
|
||||||
<tr>
|
|
||||||
<td class="text-capitalize">{{ $language->name }}</td>
|
|
||||||
<td>
|
|
||||||
<div class="form-group">
|
|
||||||
<form action="#">
|
|
||||||
<input onchange="update_language_dir('{{ $language->id }}', 'ltr')" name="direction" id="direction_ltr{{ $language->id }}" type="radio" value="ltr" @if ($language->direction == 'ltr') checked @endif>
|
|
||||||
<label for="direction_ltr{{ $language->id }}">{{ get_phrase('LTR') }}</label>
|
|
||||||
|
|
||||||
<input onchange="update_language_dir('{{ $language->id }}', 'rtl')" name="direction" id="direction_rtl{{ $language->id }}" type="radio" value="rtl" @if ($language->direction == 'rtl') checked @endif>
|
|
||||||
<label for="direction_rtl{{ $language->id }}">{{ get_phrase('RTL') }}</label>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="">
|
|
||||||
<a href="{{ route('admin.language.phrase.edit', ['lan_id' => $language->id]) }}" class="btn btn-light-white">{{ get_phrase('Edit phrase') }}</a>
|
|
||||||
|
|
||||||
@if ($language->name == 'english' || $language->name == 'English')
|
|
||||||
@else
|
|
||||||
<a href="{{ route('admin.language.export', ['id' => $language->id]) }}" class="btn btn-light-white">{{ get_phrase('Export language') }}</a>
|
|
||||||
<a href="javascript:;" onclick="confirmModal('{{ route('admin.language.delete', ['id' => $language->id]) }}')" class="btn btn-light-white">{{ get_phrase('Delete language') }}</a>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!----TABLE LISTING ENDS--->
|
|
||||||
</div>
|
|
||||||
<div class="tab-pane fade" id="cProfile" role="tabpanel" aria-labelledby="cProfile-tab">
|
|
||||||
<!----ADD NEW LANGUAGE---->
|
|
||||||
<div class="tab-pane" id="add_lang">
|
|
||||||
<div class="row m-2">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<form action="{{ route('admin.language.store') }}" method="post">
|
|
||||||
@csrf
|
|
||||||
<div class="fpb7 mb-2">
|
|
||||||
<label for="language" class="form-label ol-form-label">{{ get_phrase('Add new language') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control" id="language" name="language" placeholder="{{ get_phrase('No special character or space is allowed. Valid examples: French, Spanish, Bengali etc') }}">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn ol-btn-primary">
|
|
||||||
{{ get_phrase('Save') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!----LANGUAGE ADDING FORM ENDS-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-pane fade" id="cMessage" role="tabpanel" aria-labelledby="cMessage-tab">
|
|
||||||
<div class="tab-pane p-3" id="import_language">
|
|
||||||
<div class="row">
|
|
||||||
<form action="{{ route('admin.language.import') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<div class="col-md-8 fpb-7 mb-2">
|
|
||||||
<label for="formFile" class="form-label ol-form-label">{{ get_phrase('Import your language files from here. (Ex: english.json)') }}</label>
|
|
||||||
<input class="form-control ol-form-control" type="file" id="formFile" name="language_file" accept=".json" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-8 fpb-7 mb-2">
|
|
||||||
<label for="language_id" class="form-label ol-form-label">{{ get_phrase('Select Language to Replace') }}</label>
|
|
||||||
<select name="language_id" id="language_id" class="form-control ol-form-control" required>
|
|
||||||
@foreach ($languages as $language)
|
|
||||||
@if ($language->name !== 'English')
|
|
||||||
<!-- Skip default language (English) -->
|
|
||||||
<option value="{{ $language->id }}">{{ ucfirst($language->name) }}</option>
|
|
||||||
@endif
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn ol-btn-primary">{{ get_phrase('Import') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function updatePhrase(key, key_main) {
|
|
||||||
$('#btn-' + key).text('...');
|
|
||||||
var updatedValue = $('#phrase-' + key).val();
|
|
||||||
var currentEditingLanguage = '<?php echo isset($current_editing_language) ? $current_editing_language : ''; ?>';
|
|
||||||
$.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: "",
|
|
||||||
data: {
|
|
||||||
updatedValue: updatedValue,
|
|
||||||
currentEditingLanguage: currentEditingLanguage,
|
|
||||||
key: key_main
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
$('#btn-' + key).html('<i class = "mdi mdi-check-circle"></i>');
|
|
||||||
success('<?php echo get_phrase('phrase_updated'); ?>');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_language_dir(language_id, dir) {
|
|
||||||
$.ajax({
|
|
||||||
type: 'post',
|
|
||||||
url: '{{ route('admin.language.direction.update') }}',
|
|
||||||
data: {
|
|
||||||
language_id: language_id,
|
|
||||||
direction: dir
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
success('{{ get_phrase('Direction has been updated') }}');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,175 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('System settings'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<!-- Mani section header and breadcrumb -->
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-4 px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('System Settings') }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xl-7">
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<h3 class="title text-14px mb-3">{{ get_phrase('System Settings') }}</h3>
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
|
|
||||||
<form class="required-form" action="{{ route('admin.system.settings.update') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="system_name">{{ get_phrase('Website name') }}<span>*</span></label>
|
|
||||||
<input type="text" name = "system_name" id = "system_name" class="form-control ol-form-control" value="{{ get_settings('system_name') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="system_title">{{ get_phrase('Website title') }}<span>*</span></label>
|
|
||||||
<input type="text" name = "system_title" id = "system_title" class="form-control ol-form-control" value="{{ get_settings('system_title') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="website_keywords" class="form-label ol-form-label">{{ get_phrase('Website keywords') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control bootstrap-tag-input w-100" id = "website_keywords" name="website_keywords" data-role="tagsinput" value="{{ get_settings('website_keywords') }}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="website_description">{{ get_phrase('Website description') }}</label>
|
|
||||||
<textarea name="website_description" id = "website_description" class="form-control ol-form-control" rows="5">{{ get_settings('website_description') }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="author">{{ get_phrase('Author') }}</label>
|
|
||||||
<input type="text" name = "author" id = "author" class="form-control ol-form-control" value="{{ get_settings('author') }}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="slogan">{{ get_phrase('Slogan') }}<span>*</span></label>
|
|
||||||
<input type="text" name = "slogan" id = "slogan" class="form-control ol-form-control" value="{{ get_settings('slogan') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="system_email">{{ get_phrase('System email') }}<span>*</span></label>
|
|
||||||
<input type="text" name = "system_email" id = "system_email" class="form-control ol-form-control" value="{{ get_settings('system_email') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="address">{{ get_phrase('Address') }}</label>
|
|
||||||
<textarea name="address" id = "address" class="form-control ol-form-control" rows="5">{{ get_settings('address') }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="phone">{{ get_phrase('Phone') }}</label>
|
|
||||||
<input type="text" name = "phone" id = "phone" class="form-control ol-form-control" value="{{ get_settings('phone') }}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="youtube_api_key">{{ get_phrase('Youtube API key') }}<span>*</span> <a href = "https://developers.google.com/youtube/v3/getting-started" target = "_blank" class="text-12px text-secondary">({{ get_phrase('Get YouTube API key') }} <i class="mdi mdi-open-in-new"></i>)</a></label>
|
|
||||||
<input type="text" name = "youtube_api_key" id = "youtube_api_key" class="form-control ol-form-control" value="{{ get_settings('youtube_api_key') }}" required>
|
|
||||||
<a href="https://support.google.com/googleapi/answer/6158841" target="_blank" class="text-12px text-secondary">
|
|
||||||
{{ get_phrase('If you want to use Google Drive video, you need to enable the Google Drive service in this API') }}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="vimeo_api_key">{{ get_phrase('Vimeo API key') }}<span>*</span>
|
|
||||||
<a href = "https://www.youtube.com/watch?v=Wwy9aibAd54" target = "_blank" class="text-12px text-secondary">({{ get_phrase('get Vimeo API key') }} <i class="mdi mdi-open-in-new"></i>)</a></label>
|
|
||||||
<input type="text" name = "vimeo_api_key" id = "vimeo_api_key" class="form-control ol-form-control" value="{{ get_settings('vimeo_api_key') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="purchase_code">{{ get_phrase('Purchase code') }}<span class="form-label ol-form-label">*</span></label>
|
|
||||||
<input type="text" name = "purchase_code" id = "purchase_code" class="form-control ol-form-control" value="{{ get_settings('purchase_code') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="language">{{ get_phrase('System language') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="language" id="language">
|
|
||||||
@foreach(App\Models\Language::get() as $language)
|
|
||||||
<option value="{{strtolower($language->name)}}" @if (get_settings('language') == strtolower($language->name)) selected @endif>{{ $language->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3 ">
|
|
||||||
<label class="form-label ol-form-label" for="course_selling_tax">{{ get_phrase('Course selling tax') }} (%)
|
|
||||||
<span>*</span></label>
|
|
||||||
<div class="input-group">
|
|
||||||
<input type="number" value="{{ get_settings('course_selling_tax') }}" min="0" max="100" id="course_selling_tax" name="course_selling_tax" class="form-control ol-form-control" required>
|
|
||||||
<div class="input-group-append">
|
|
||||||
<span class="input-group-text ol-form-control">%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<small>{{ get_phrase('Enter 0 if you want to disable the tax option') }}</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="student_email_verification">{{ get_phrase('Student email verification') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="student_email_verification" id="student_email_verification">
|
|
||||||
<option value="0" @if (get_settings('student_email_verification') != 1) selected @endif>{{ get_phrase('Disabled') }}</option>
|
|
||||||
<option value="1" @if (get_settings('student_email_verification') == 1) selected @endif>{{ get_phrase('Enabled') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="device_limitation">{{ get_phrase('Device limitation') }}</label>
|
|
||||||
<input type="number" name="device_limitation" id="device_limitation" class="form-control ol-form-control" value="{{ get_settings('device_limitation') }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="eForm-label" for="timezone">{{ get_phrase('Timezone') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" id="timezone" name="timezone" required>
|
|
||||||
@php $tzlist = DateTimeZone::listIdentifiers(DateTimeZone::ALL); @endphp
|
|
||||||
@foreach ($tzlist as $tz)
|
|
||||||
<option value="{{ $tz }}" {{ get_settings('timezone') == $tz ? 'selected':'' }}>{{ $tz }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="footer_text">{{ get_phrase('Footer text') }}</label>
|
|
||||||
<input type="text" name = "footer_text" id = "footer_text" class="form-control ol-form-control" value="{{ get_settings('footer_text') }}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="footer_link">{{ get_phrase('Footer link') }}</label>
|
|
||||||
<input type="text" name = "footer_link" id = "footer_link" class="form-control ol-form-control" value="{{ get_settings('footer_link') }}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn ol-btn-primary" onclick="checkRequiredFields()">{{ get_phrase('Save Changes') }}</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div> <!-- end card body-->
|
|
||||||
</div> <!-- end card -->
|
|
||||||
</div><!-- end col-->
|
|
||||||
<div class="col-xl-5">
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<h3 class="title text-14px mb-3">{{ get_phrase('Update Product') }}</h3>
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<form action="{{ route('admin.product.update') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" class="">{{ get_phrase('File') }}</label>
|
|
||||||
|
|
||||||
<input type="file" class="form-control ol-form-control" id="file_name" name="file" required onchange="changeTitleOfImageUploader(this)">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn ol-btn-primary">{{ get_phrase('Update') }}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div> <!-- end card body-->
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
@push('js')@endpush
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
<div class="row mb-3">
|
|
||||||
<label for="email" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Email') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="email" name="email" class="form-control ol-form-control" id="email" @isset($student->email) value="{{ $instructor->email }}" @endisset required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-3">
|
|
||||||
<div class="col-sm-8 offset-sm-2">
|
|
||||||
<input type="hidden" name="email_verified" value="0">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="email_verified" name="email_verified" value="1">
|
|
||||||
<label class="form-check-label" for="email_verified">{{ get_phrase('Mark email as verified') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (!isset($student->email))
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="password" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Password') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<input type="password" name="password" class="form-control ol-form-control" id="password">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endisset
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
@extends('layouts.admin')
|
|
||||||
@push('title', get_phrase('Student'))
|
|
||||||
@push('meta')
|
|
||||||
@endpush
|
|
||||||
@push('css')
|
|
||||||
@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Student List') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('admin.student.create') }}" class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add new Student') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ol-card p-4">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
|
|
||||||
<div class="row print-d-none mb-3 mt-3 row-gap-3">
|
|
||||||
<div class="col-md-6 pt-2 pt-md-0">
|
|
||||||
<div class="custom-dropdown">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="downloadPDF('.print-table', 'student-list')"><i class="fi-rr-file-pdf"></i> {{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<form class="form-inline" action="{{ route('admin.student.index') }}" method="get">
|
|
||||||
<div class="row row-gap-3">
|
|
||||||
<div class="col-md-9">
|
|
||||||
<input type="text" class="form-control ol-form-control" name="search" value="{{ request('search') }}" placeholder="{{ get_phrase('Search user') }}" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<button type="submit" class="btn ol-btn-primary w-100" id="submit-button"> {{ get_phrase('Search') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mt-4">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<!-- Table -->
|
|
||||||
@if (count($students) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($students) . ' ' . get_phrase('of') . ' ' . $students->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive course_list" id="course_list">
|
|
||||||
<table class="table eTable eTable-2 print-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('Name') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Phone') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Enrolled Course') }}</th>
|
|
||||||
<th class="print-d-none" scope="col">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($students as $key => $row)
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ ++$key }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_img">
|
|
||||||
<img class="img-fluid rounded-circle image-45" width="45" height="45" src="{{ get_image($row->photo) }}" />
|
|
||||||
</div>
|
|
||||||
<div class="ms-1">
|
|
||||||
<h4 class="title fs-14px">{{ $row->name }}</h4>
|
|
||||||
<p class="sub-title2 text-12px">{{ $row->email }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name min-w-150px">
|
|
||||||
<p>{{ $row->phone }}</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{ App\Models\Enrollment::where('user_id', $row->id)->count() }}
|
|
||||||
{{ get_phrase('Courses') }}
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ route('admin.student.edit', $row->id) }}">{{ get_phrase('Edit') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('admin.student.delete', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Remove account') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('admin.no_data')
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<!-- Data info and Pagination -->
|
|
||||||
@if (count($students) > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($students) . ' ' . get_phrase('of') . ' ' . $students->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $students->links() }}
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
@endpush
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
@extends('layouts.' . get_frontend_settings('theme'))
|
|
||||||
@push('title', get_phrase('Sign Up'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')
|
|
||||||
<style>
|
|
||||||
.form-icons .right {
|
|
||||||
right: 20px;
|
|
||||||
cursor: pointer !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@endpush
|
|
||||||
@section('content')
|
|
||||||
<section class="login-area">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-7 col-md-6">
|
|
||||||
<div class="login-img">
|
|
||||||
<img src="{{ asset('assets/frontend/' . get_frontend_settings('theme') . '/image/signup.gif') }}" alt="register-banner">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-5 col-md-6">
|
|
||||||
<form action="{{ route('register') }}" class="global-form login-form mt-25" id="login-form" method="post" enctype="multipart/form-data">@csrf
|
|
||||||
<h4 class="g-title">{{ get_phrase('Sign Up') }}</h4>
|
|
||||||
<p class="description">{{ get_phrase('See your growth and get consulting support! ') }}</p>
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="" class="form-label">{{ get_phrase('Name') }}</label>
|
|
||||||
<input type="text" name="name" class="form-control" placeholder="Your Name">
|
|
||||||
|
|
||||||
@error('name')
|
|
||||||
<small class="text-danger">{{ $message }}</small>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="" class="form-label">{{ get_phrase('Email') }}</label>
|
|
||||||
<input type="email" name="email" class="form-control" placeholder="Your Email">
|
|
||||||
|
|
||||||
@error('email')
|
|
||||||
<small class="text-danger">{{ $message }}</small>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="" class="form-label">{{ get_phrase('Password') }}</label>
|
|
||||||
<input type="password" name="password" class="form-control" placeholder="*********">
|
|
||||||
|
|
||||||
@error('password')
|
|
||||||
<small class="text-danger">{{ $message }}</small>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (get_settings('allow_instructor'))
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<input id="instructor" type="checkbox" name="instructor">
|
|
||||||
<label for="instructor">{{ get_phrase('Apply to Become an instructor') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="become-instructor-fields" class="d-none">
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="phone" class="form-label">{{ get_phrase('Phone') }}</label>
|
|
||||||
<input class="form-control" id="phone" type="phone" name="phone" placeholder="{{ get_phrase('Enter your phone number') }}" required>
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="document" class="form-label">{{ get_phrase('Document') }} <small>(doc, docs, pdf, txt, png, jpg, jpeg)</small></label>
|
|
||||||
<input class="form-control" id="document" type="file" name="document">
|
|
||||||
<small>{{ get_phrase('Provide some documents about your qualifications') }}</small>
|
|
||||||
</div>
|
|
||||||
<div class="form-group mb-5">
|
|
||||||
<label for="description" class="form-label">{{ get_phrase('Message') }}</label>
|
|
||||||
<textarea class="form-control" id="description" name="description" rows="4"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@if (get_frontend_settings('recaptcha_status'))
|
|
||||||
<button class="eBtn gradient w-100 g-recaptcha" data-sitekey="{{ get_frontend_settings('recaptcha_sitekey') }}" data-callback='onLoginSubmit' data-action='submit'>{{ get_phrase('Sign Up') }}</button>
|
|
||||||
@else
|
|
||||||
<button type="submit" class="eBtn gradient w-100">{{ get_phrase('Sign Up') }}</button>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<p class="mt-20">{{ get_phrase('Already have account?') }} <a href="{{ route('login') }}">{{ get_phrase('Sign in') }}</a></p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#showpassword').on('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const type = $('#password').attr('type');
|
|
||||||
|
|
||||||
if (type == 'password') {
|
|
||||||
$('#password').attr('type', 'text');
|
|
||||||
} else {
|
|
||||||
$('#password').attr('type', 'password');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#showcpassword').on('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const type = $('#cpassword').attr('type');
|
|
||||||
|
|
||||||
if (type == 'password') {
|
|
||||||
$('#cpassword').attr('type', 'text');
|
|
||||||
} else {
|
|
||||||
$('#cpassword').attr('type', 'password');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function onLoginSubmit(token) {
|
|
||||||
document.getElementById("login-form").submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#instructor').on('change', function() {
|
|
||||||
if ($(this).is(':checked')) {
|
|
||||||
$('#become-instructor-fields').removeClass('d-none');
|
|
||||||
} else {
|
|
||||||
$('#become-instructor-fields').addClass('d-none');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
@if ($class->enrolled_user && auth()->user()->id)
|
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
{{ config(['app.name' => get_settings('system_title')]) }}
|
|
||||||
<title>{{ $class->title }} | {{ config('app.name') }}</title>
|
|
||||||
<!-- Required meta tags -->
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link rel="shortcut icon" href="{{ asset(get_frontend_settings('favicon')) }}" />
|
|
||||||
<link rel="stylesheet" href="{{ asset('assets/frontend/default/css/bootstrap.min.css') }}">
|
|
||||||
<script src="{{ asset('assets/frontend/default/js/jquery-3.7.1.min.js') }}"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="{{ asset('assets/global/plyr/plyr.css') }}" />
|
|
||||||
<script src="{{ asset('assets/global/plyr/plyr.js') }}"></script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
html {
|
|
||||||
background-color: #212529;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-btn {
|
|
||||||
position: absolute;
|
|
||||||
top: 30px;
|
|
||||||
left: 20px;
|
|
||||||
z-index: 999;
|
|
||||||
border-radius: 50px;
|
|
||||||
background: rgba(127, 127, 127, 0.38);
|
|
||||||
text-decoration: none;
|
|
||||||
width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: width 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-btn:hover {
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-btn .icon {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-btn .icon span {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-btn span svg path {
|
|
||||||
fill: #a5a5a5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-label {
|
|
||||||
width: 75px;
|
|
||||||
height: 75px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
color: #a5a5a5;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
<div class="content-player bg-dark">
|
|
||||||
<a href="{{ route('my.bootcamp.details', $class->bootcamp_slug) }}" class="eBtn gradient back-btn">
|
|
||||||
<div class="icon">
|
|
||||||
<span class="d-inline-flex">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 24 24" width="25" height="25">
|
|
||||||
<path d="m13.646,18.342l-5.281-5.281c-.283-.283-.439-.66-.439-1.061s.156-.777.439-1.061l5.281-5.281.707.707-5.281,5.281c-.094.095-.146.22-.146.354s.052.259.146.354l5.281,5.281-.707.707Z" />
|
|
||||||
</svg>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span class="icon-label">{{ get_phrase('Go Back') }}</span>
|
|
||||||
</a>
|
|
||||||
<div class="row justify-content-center">
|
|
||||||
<div class="col-auto">
|
|
||||||
<video id="player" playsinline controls oncontextmenu="return false;" controlslist="nodownload">
|
|
||||||
<source src="{{ asset($class->file) }}" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
var player = new Plyr('#player', {
|
|
||||||
youtube: {
|
|
||||||
// Options for YouTube player
|
|
||||||
controls: 1, // Show YouTube controls
|
|
||||||
modestBranding: false, // Show YouTube logo
|
|
||||||
showinfo: 1, // Show video title and uploader on play
|
|
||||||
rel: 0, // Show related videos at the end
|
|
||||||
iv_load_policy: 3, // Do not show video annotations
|
|
||||||
cc_load_policy: 1, // Show captions by default
|
|
||||||
autoplay: false, // Do not autoplay
|
|
||||||
loop: false, // Do not loop the video
|
|
||||||
mute: false, // Do not mute the video
|
|
||||||
start: 0, // Start at this time (in seconds)
|
|
||||||
end: null // End at this time (in seconds)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@endif
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
{{-- To make a editable image or text need to be add a "builder editable" class and builder identity attribute with a unique value --}}
|
|
||||||
{{-- builder identity and builder editable --}}
|
|
||||||
{{-- builder identity value have to be unique under a single file --}}
|
|
||||||
|
|
||||||
@if (get_frontend_settings('recaptcha_status'))
|
|
||||||
@push('js')
|
|
||||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
|
||||||
@endpush
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<footer class="footer-area">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4 col-md-4">
|
|
||||||
<div class="footer-content">
|
|
||||||
<img src="{{ get_image(get_frontend_settings('light_logo')) }}" alt="system logo">
|
|
||||||
<p class="description builder-editable" builder-identity="1">{{ get_phrase("It is a long established fact that a reader will be the distract by the read content of a page layout.") }}</p>
|
|
||||||
|
|
||||||
<ul class="f-socials d-flex">
|
|
||||||
<li><a href="{{ get_frontend_settings('twitter') }}"><i class="fa-brands fa-twitter"></i></a>
|
|
||||||
</li>
|
|
||||||
<li><a href="{{ get_frontend_settings('facebook') }}"><i class="fa-brands fa-facebook-f"></i></a></li>
|
|
||||||
<li><a href="{{ get_frontend_settings('linkedin') }}"><i class="fa-brands fa-linkedin-in"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
<div class="gradient-border2">
|
|
||||||
<a href="{{ route('contact.us') }}" class="gradient-border-btn">
|
|
||||||
{{ get_phrase('Contact with Us') }}
|
|
||||||
<i class="fa-solid fa-arrow-right-long ms-2"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-8 col-md-8">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-3 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Top Categories') }}</h4>
|
|
||||||
<ul>
|
|
||||||
@foreach (top_categories() as $category)
|
|
||||||
<li>
|
|
||||||
<a href="{{ route('courses', $category->slug) }}">
|
|
||||||
{{ ucfirst($category->title) }}</a>
|
|
||||||
</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-3 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Useful links') }}</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="{{ route('courses') }}">{{ get_phrase('Course') }}</a></li>
|
|
||||||
<li><a href="{{ route('blogs') }}">{{ get_phrase('Blog') }}</a></li>
|
|
||||||
<li><a href="{{ route('knowledge.base.topicks') }}">{{ get_phrase('Knowledge Base') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Company') }}</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="#">
|
|
||||||
{{ get_phrase('Phone : ') }}
|
|
||||||
{{ get_settings('phone') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#">
|
|
||||||
{{ get_phrase('Email : ') }}
|
|
||||||
{{ get_settings('system_email') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="newslater-bottom">
|
|
||||||
<h4 class="builder-editable" builder-identity="2">{{ get_phrase("Newsletter") }}</h4>
|
|
||||||
<p class="description builder-editable" builder-identity="3">{{ get_phrase("Subscribe to stay tuned for new web design and latest updates. Let's do it!") }}</p>
|
|
||||||
<form action="{{ route('newsletter.store') }}" method="post" class="newslater-form" id="newslater-form">
|
|
||||||
@csrf
|
|
||||||
<input type="text" name="email" class="form-control" placeholder="{{ get_phrase('Email address') }}">
|
|
||||||
@if(get_frontend_settings('recaptcha_status'))
|
|
||||||
<button class="eBtn gradient g-recaptcha" data-sitekey="{{ get_frontend_settings('recaptcha_sitekey') }}" data-callback='onNewslaterSubmit' data-action='submit'>{{ get_phrase('Submit') }}</button>
|
|
||||||
@else
|
|
||||||
<button class="eBtn gradient">{{ get_phrase('Submit') }}</button>
|
|
||||||
@endif
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer-bottom">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8">
|
|
||||||
<ul class="footer-policy">
|
|
||||||
<li><a href="{{ route('about.us') }}">{{ get_phrase('About Us') }}</a></li>
|
|
||||||
<li><a href="{{ route('privacy.policy') }}">{{ get_phrase('Privacy Policy') }}</a></li>
|
|
||||||
<li><a href="{{ route('terms.condition') }}">{{ get_phrase('Terms And Use') }}</a></li>
|
|
||||||
<li><a href="{{ route('refund.policy') }}">{{ get_phrase('Sales and Refunds') }}</a></li>
|
|
||||||
<li><a href="{{ route('cookie.policy') }}">{{ get_phrase('Cookie Policy') }}</a></li>
|
|
||||||
<li><a href="{{ route('faq') }}">{{ get_phrase('FAQ') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4">
|
|
||||||
<div class="copyright-text">
|
|
||||||
<p class="builder-editable" builder-identity="4">{{ get_phrase("© 2024 All Rights Reserved") }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function onNewslaterSubmit(token) {
|
|
||||||
document.getElementById("newslater-form").submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
{{-- To make a editable image or text need to be add a "builder editable" class and builder identity attribute with a unique value --}}
|
|
||||||
{{-- builder identity and builder editable --}}
|
|
||||||
{{-- builder identity value have to be unique under a single file --}}
|
|
||||||
|
|
||||||
@if (get_frontend_settings('recaptcha_status'))
|
|
||||||
@push('js')
|
|
||||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
|
||||||
@endpush
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<footer class="footer-area">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-4 col-md-4">
|
|
||||||
<div class="footer-content">
|
|
||||||
<img src="{{ get_image(get_frontend_settings('light_logo')) }}" alt="system logo">
|
|
||||||
<p class="description builder-editable" builder-identity="1">{{get_phrase('It is a long established fact that a reader will be the distract by the read content of a page layout')}}.</p>
|
|
||||||
|
|
||||||
<ul class="f-socials d-flex">
|
|
||||||
<li><a href="{{ get_frontend_settings('twitter') }}"><i class="fa-brands fa-twitter"></i></a>
|
|
||||||
</li>
|
|
||||||
<li><a href="{{ get_frontend_settings('facebook') }}"><i class="fa-brands fa-facebook-f"></i></a></li>
|
|
||||||
<li><a href="{{ get_frontend_settings('linkedin') }}"><i class="fa-brands fa-linkedin-in"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
<div class="gradient-border2">
|
|
||||||
<a href="{{ route('contact.us') }}" class="gradient-border-btn">
|
|
||||||
{{ get_phrase('Contact with Us') }}
|
|
||||||
<i class="fa-solid fa-arrow-right-long ms-2"></i></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-8 col-md-8">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-3 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Top Categories') }}</h4>
|
|
||||||
<ul>
|
|
||||||
@foreach (top_categories() as $category)
|
|
||||||
<li>
|
|
||||||
<a href="{{ route('courses', $category->slug) }}">
|
|
||||||
{{ ucfirst($category->title) }}</a>
|
|
||||||
</li>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-3 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Useful links') }}</h4>
|
|
||||||
<ul>
|
|
||||||
<li><a href="{{ route('courses') }}">{{ get_phrase('Course') }}</a></li>
|
|
||||||
<li><a href="{{ route('blogs') }}">{{ get_phrase('Blog') }}</a></li>
|
|
||||||
<li><a href="{{ route('knowledge.base.topicks') }}">{{ get_phrase('Knowledge Base') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 col-md-6">
|
|
||||||
<div class="footer-widget">
|
|
||||||
<h4>{{ get_phrase('Company') }}</h4>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="#">
|
|
||||||
{{ get_phrase('Phone : ') }}
|
|
||||||
{{ get_settings('phone') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#">
|
|
||||||
{{ get_phrase('Email : ') }}
|
|
||||||
{{ get_settings('system_email') }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="newslater-bottom">
|
|
||||||
<h4 class="builder-editable" builder-identity="2">{{ get_phrase('Newsletter') }}</h4>
|
|
||||||
<p class="description builder-editable" builder-identity="3">{{ get_phrase("Subscribe to stay tuned for new web design and latest updates. Let's do it!") }}</p>
|
|
||||||
<form action="{{ route('newsletter.store') }}" method="post" class="newslater-form" id="newslater-form">
|
|
||||||
@csrf
|
|
||||||
<input type="text" name="email" class="form-control" placeholder="{{ get_phrase('Email address') }}">
|
|
||||||
@if(get_frontend_settings('recaptcha_status'))
|
|
||||||
<button class="eBtn gradient g-recaptcha" data-sitekey="{{ get_frontend_settings('recaptcha_sitekey') }}" data-callback='onNewslaterSubmit' data-action='submit'>{{ get_phrase('Submit') }}</button>
|
|
||||||
@else
|
|
||||||
<button class="eBtn gradient">{{ get_phrase('Submit') }}</button>
|
|
||||||
@endif
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="footer-bottom">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-8">
|
|
||||||
<ul class="footer-policy">
|
|
||||||
<li><a href="{{ route('about.us') }}">{{ get_phrase('About Us') }}</a></li>
|
|
||||||
<li><a href="{{ route('privacy.policy') }}">{{ get_phrase('Privacy Policy') }}</a></li>
|
|
||||||
<li><a href="{{ route('terms.condition') }}">{{ get_phrase('Terms And Use') }}</a></li>
|
|
||||||
<li><a href="{{ route('refund.policy') }}">{{ get_phrase('Sales and Refunds') }}</a></li>
|
|
||||||
<li><a href="{{ route('cookie.policy') }}">{{ get_phrase('Cookie Policy') }}</a></li>
|
|
||||||
<li><a href="{{ route('faq') }}">{{ get_phrase('FAQ') }}</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-4">
|
|
||||||
<div class="copyright-text">
|
|
||||||
<p class="builder-editable" builder-identity="4">{{ get_phrase('© 2024 All Rights Reserved') }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function onNewslaterSubmit(token) {
|
|
||||||
document.getElementById("newslater-form").submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
$.ajaxSetup({
|
|
||||||
headers: {
|
|
||||||
"X-CSRF-TOKEN": '{{ csrf_token() }}'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.flexCheckChecked').on('change', function(e) {
|
|
||||||
const id = $(this).attr('id');
|
|
||||||
const Elem = $(this);
|
|
||||||
|
|
||||||
Elem.attr('disabled', true);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('set.watch.history') }}", // Your route
|
|
||||||
type: "post",
|
|
||||||
data: {
|
|
||||||
lesson_id: id,
|
|
||||||
course_id: "{{ $course_details->id }}"
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
Elem.attr('disabled', false);
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
Elem.attr('disabled', false);
|
|
||||||
console.error("Error updating watch history:", xhr.responseText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#fullscreen').on('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
$('#player_content').toggleClass('col-lg-8 col-12');
|
|
||||||
$('#player_side_bar').toggleClass('col-lg-4 col-12');
|
|
||||||
});
|
|
||||||
|
|
||||||
function initializeSummernote() {
|
|
||||||
$('textarea#summernote').summernote({
|
|
||||||
height: 180, // set editor height
|
|
||||||
minHeight: null, // set minimum height of editor
|
|
||||||
maxHeight: null, // set maximum height of editor
|
|
||||||
focus: true, // set focus to editable area after initializing summernote
|
|
||||||
toolbar: [
|
|
||||||
['color', ['color']],
|
|
||||||
['font', ['bold', 'italic', 'underline', 'clear']],
|
|
||||||
['fontsize', ['fontsize']],
|
|
||||||
['para', ['ul', 'ol']],
|
|
||||||
['table', ['table']],
|
|
||||||
['insert', ['link']]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeSummernote();
|
|
||||||
});
|
|
||||||
|
|
||||||
var formElement;
|
|
||||||
if ($('.ajaxForm:not(.initialized)').length > 0) {
|
|
||||||
$('.ajaxForm:not(.initialized)').ajaxForm({
|
|
||||||
beforeSend: function(data, form) {
|
|
||||||
var formElement = $(form);
|
|
||||||
},
|
|
||||||
uploadProgress: function(event, position, total, percentComplete) {},
|
|
||||||
complete: function(xhr) {
|
|
||||||
|
|
||||||
},
|
|
||||||
error: function(e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('.ajaxForm:not(.initialized)').addClass('initialized');
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.tagify:not(.inited)').each(function(index, element) {
|
|
||||||
var tagify = new Tagify(element, {
|
|
||||||
placeholder: '{{ get_phrase('Enter your keywords') }}',
|
|
||||||
delimiters: "~",
|
|
||||||
});
|
|
||||||
$(element).addClass('inited');
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
var iframeWidth = $('.embed-responsive-item').width();
|
|
||||||
console.log(iframeWidth)
|
|
||||||
var iframeHeight = (iframeWidth/100)*56;
|
|
||||||
console.log(iframeHeight)
|
|
||||||
$('.embed-responsive-item').height(iframeHeight+'px');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@if (get_player_settings('watermark_type') == 'js')
|
|
||||||
<script>
|
|
||||||
// append watermark in player
|
|
||||||
function prependWatermark() {
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: "{{ route('player.prepend.watermark') }}",
|
|
||||||
success: function(response) {
|
|
||||||
if (response) {
|
|
||||||
$('.plyr__video-wrapper').prepend(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
if($('.plyr__video-wrapper .watermark-container').length == 0){
|
|
||||||
prependWatermark();
|
|
||||||
}
|
|
||||||
}, 5000);
|
|
||||||
</script>
|
|
||||||
@endif
|
|
||||||
@ -1,253 +0,0 @@
|
|||||||
@push('js')
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
var player = new Plyr('#player', {
|
|
||||||
youtube: {
|
|
||||||
// Options for YouTube player
|
|
||||||
controls: 1, // Show YouTube controls
|
|
||||||
modestBranding: false, // Show YouTube logo
|
|
||||||
showinfo: 1, // Show video title and uploader on play
|
|
||||||
rel: 0, // Show related videos at the end
|
|
||||||
iv_load_policy: 3, // Do not show video annotations
|
|
||||||
cc_load_policy: 1, // Show captions by default
|
|
||||||
autoplay: false, // Do not autoplay
|
|
||||||
loop: false, // Do not loop the video
|
|
||||||
mute: false, // Do not mute the video
|
|
||||||
start: 0, // Start at this time (in seconds)
|
|
||||||
end: null // End at this time (in seconds)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
|
|
||||||
<style type="text/css">
|
|
||||||
.plyr__progress video {
|
|
||||||
width: 180px !important;
|
|
||||||
height: auto !important;
|
|
||||||
position: absolute !important;
|
|
||||||
bottom: 30px !important;
|
|
||||||
z-index: 1 !important;
|
|
||||||
border-radius: 10px !important;
|
|
||||||
border: 2px solid #fff !important;
|
|
||||||
display: none;
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.plyr__progress video:hover {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
video:not(.plyr:fullscreen video) {
|
|
||||||
width: 100%;
|
|
||||||
max-height: auto !important;
|
|
||||||
max-height: 567px !important;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overlay and progress bar styling */
|
|
||||||
.overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(0, 0, 0, 0.7);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
z-index: 9999;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Circular progress bar container */
|
|
||||||
.circular-progress-container {
|
|
||||||
position: relative;
|
|
||||||
width: 100px;
|
|
||||||
height:100px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Outer circle border (for border effect) */
|
|
||||||
.outer-circle {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 50%;
|
|
||||||
stroke: #ddd; /* Border color */
|
|
||||||
stroke-width: 7;
|
|
||||||
fill: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Inner circle for progress animation */
|
|
||||||
.circular-progress {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 50%;
|
|
||||||
stroke-dasharray: 440; /* Circumference of the circle */
|
|
||||||
stroke-dashoffset: 440;
|
|
||||||
stroke: #6610f2; /* Progress color */
|
|
||||||
stroke-width: 7;
|
|
||||||
fill: none;
|
|
||||||
transition: stroke-dashoffset 5s linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.progress-ring {
|
|
||||||
transform: rotate(-90deg); /* To start progress from the top */
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 6px;
|
|
||||||
right: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
background: #ff0000;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 18px;
|
|
||||||
height: 30px;
|
|
||||||
width: 30px;
|
|
||||||
line-height: 32px;
|
|
||||||
border-radius: 50%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.overlay-text {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #ffffff;
|
|
||||||
text-align: center;
|
|
||||||
top: 70%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="overlay" id="nextVideoOverlay">
|
|
||||||
<div class="circular-progress-container">
|
|
||||||
<svg class="progress-ring" width="100" height="100">
|
|
||||||
<!-- Outer Circle (border) -->
|
|
||||||
<circle class="outer-circle" cx="50" cy="50" r="45" />
|
|
||||||
<!-- Inner Circle (progress) -->
|
|
||||||
<circle class="circular-progress" cx="50" cy="50" r="45" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="overlay-text">Playing next video in <span id="countdown">5</span> sec</div>
|
|
||||||
<div class="cancel-icon" id="cancelNextVideo">✖</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
// Define elements for overlay and countdown
|
|
||||||
const overlay = document.getElementById('nextVideoOverlay');
|
|
||||||
const countdownElement = document.getElementById('countdown');
|
|
||||||
const cancelNextVideoButton = document.getElementById('cancelNextVideo');
|
|
||||||
let countdownInterval;
|
|
||||||
|
|
||||||
// Function to start countdown
|
|
||||||
function startCountdown() {
|
|
||||||
let countdown = 5; // Countdown set to 5 seconds
|
|
||||||
countdownElement.textContent = countdown;
|
|
||||||
overlay.style.visibility = 'visible';
|
|
||||||
|
|
||||||
// Restart the circular progress animation
|
|
||||||
const circleProgress = document.querySelector('.circular-progress');
|
|
||||||
circleProgress.style.transition = 'none'; // Remove previous transition
|
|
||||||
circleProgress.style.strokeDashoffset = 440; // Reset stroke offset
|
|
||||||
setTimeout(() => {
|
|
||||||
circleProgress.style.transition = 'stroke-dashoffset 5s linear';
|
|
||||||
circleProgress.style.strokeDashoffset = 0; // Animate the circle fill to complete
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
countdownInterval = setInterval(() => {
|
|
||||||
countdown -= 1;
|
|
||||||
countdownElement.textContent = countdown;
|
|
||||||
|
|
||||||
if (countdown <= 0) {
|
|
||||||
clearInterval(countdownInterval);
|
|
||||||
overlay.style.visibility = 'hidden';
|
|
||||||
|
|
||||||
let lesson_id = '{{ $lesson_details['id'] }}';
|
|
||||||
let course_id = '{{ $course_details['id'] }}';
|
|
||||||
var next_lesson_id = '{{ next_lesson($course_details['id'], $lesson_details['id']) }}';
|
|
||||||
|
|
||||||
if (next_lesson_id) {
|
|
||||||
const url = '{{ url("play-course") }}' + '/' + '{{ slugify($course_details['title']) }}' + '-' + course_id + '/' + next_lesson_id;
|
|
||||||
window.location.href = url; // Redirect to the next lesson
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Event listener for video end
|
|
||||||
if (typeof player === 'object' && player !== null) {
|
|
||||||
player.addEventListener('ended', () => {
|
|
||||||
console.log('Video has ended');
|
|
||||||
var next_lesson_id = '{{ next_lesson($course_details['id'], $lesson_details['id']) }}';
|
|
||||||
if (next_lesson_id) {
|
|
||||||
startCountdown(); // Start showing countdown when video ends
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel next video if user clicks cancel icon
|
|
||||||
cancelNextVideoButton.addEventListener('click', () => {
|
|
||||||
clearInterval(countdownInterval);
|
|
||||||
overlay.style.visibility = 'hidden';
|
|
||||||
console.log('Next video playback canceled');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Update Watch history and set current duration-->
|
|
||||||
<script type="text/javascript">
|
|
||||||
let lesson_id = '{{ $lesson_details['id'] }}';
|
|
||||||
let course_id = '{{ $course_details['id'] }}';
|
|
||||||
var currentProgress = '{{ lesson_progress($lesson_details['id']) }}';
|
|
||||||
let previousSavedDuration = 0;
|
|
||||||
let currentDuration = 0;
|
|
||||||
|
|
||||||
if (typeof player === 'object' && player !== null) {
|
|
||||||
setInterval(function() {
|
|
||||||
currentDuration = parseInt(player.currentTime);
|
|
||||||
if (lesson_id && course_id && (currentDuration % 5) == 0 && previousSavedDuration != currentDuration) {
|
|
||||||
previousSavedDuration = currentDuration;
|
|
||||||
let url = "{{ route('update_watch_history') }}";
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: 'POST',
|
|
||||||
url: url,
|
|
||||||
data: {
|
|
||||||
lesson_id: lesson_id,
|
|
||||||
course_id: course_id,
|
|
||||||
current_duration: currentDuration,
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // Add CSRF token from meta tag
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log(response);
|
|
||||||
console.log(response.course_progress);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, 900);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var watched_duration = @json(get_watched_duration($lesson_details['id'], auth()->user()->id));
|
|
||||||
|
|
||||||
watched_duration = JSON.parse(watched_duration);
|
|
||||||
|
|
||||||
var previous_duration = watched_duration && watched_duration.current_duration > 0
|
|
||||||
? watched_duration.current_duration
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
var previousTimeSetter = setInterval(function() {
|
|
||||||
if (player.playing == false && player.currentTime != previous_duration) {
|
|
||||||
player.currentTime = previous_duration;
|
|
||||||
console.log(previous_duration);
|
|
||||||
console.log(player.currentTime);
|
|
||||||
} else {
|
|
||||||
clearInterval(previousTimeSetter);
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
@if (isset($lesson_details->lesson_type))
|
|
||||||
@if ($lesson_details->lesson_type == 'text')
|
|
||||||
<div class="course-video-area border-primary">
|
|
||||||
<div class="text_show">
|
|
||||||
{!! removeScripts($lesson_details->attachment) !!}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif ($lesson_details->lesson_type == 'video-url')
|
|
||||||
<div class="course-video-area border-primary border">
|
|
||||||
<!-- Video -->
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<div id="player">
|
|
||||||
<iframe src="{{ $lesson_details->lesson_src }}?origin=https://plyr.io&iv_load_policy=3&modestbranding=1&playsinline=1&showinfo=0&rel=0&enablejsapi=1" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
|
||||||
</div>
|
|
||||||
@include('course_player.player_config')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif ($lesson_details->lesson_type == 'scorm')
|
|
||||||
<div class="course-video-area">
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<div>
|
|
||||||
@if ($lesson_details->attachment_type == 'iSpring')
|
|
||||||
<iframe class="embed-responsive-item"
|
|
||||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/res/index.html') }}"
|
|
||||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
|
||||||
@elseif ($lesson_details->attachment_type == 'articulate')
|
|
||||||
<iframe class="embed-responsive-item"
|
|
||||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/index.html') }}"
|
|
||||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
|
||||||
@elseif ($lesson_details->attachment_type == 'adobeCaptivate')
|
|
||||||
<iframe class="embed-responsive-item"
|
|
||||||
src="{{ asset('uploads/lesson_file/scorm_content/' . $lesson_details->attachment . '/index.html') }}"
|
|
||||||
allowfullscreen allowtransparency width="100%" height="100%" allow="autoplay"></iframe>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif($lesson_details->lesson_type == 'system-video')
|
|
||||||
@php
|
|
||||||
$watermark_type = get_player_settings('watermark_type');
|
|
||||||
$lesson_video = $lesson_details->lesson_src;
|
|
||||||
if ($watermark_type == 'ffmpeg') {
|
|
||||||
$origin = dirname($lesson_details->lesson_src);
|
|
||||||
$dir = $origin . '/watermark';
|
|
||||||
$file = str_replace($origin, '', $lesson_details->lesson_src);
|
|
||||||
$lesson_video = "{$dir}{$file}";
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
<div class="course-video-area border-primary border">
|
|
||||||
<!-- Video -->
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<div class=" bd-r-10 mb-16 position-relative bg-light custom-system-video">
|
|
||||||
<video id="player" playsinline controls oncontextmenu="return false;">
|
|
||||||
{{-- <source src="{{ asset($lesson_details->lesson_src) }}" type="video/mp4"> --}}
|
|
||||||
<source src="{{ route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]) }}" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
@include('course_player.player_config')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif($lesson_details->lesson_type == 'image')
|
|
||||||
@php
|
|
||||||
// $img = asset('uploads/lesson_file/attachment/' . $lesson_details->attachment);
|
|
||||||
$img = route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id])
|
|
||||||
@endphp
|
|
||||||
<img width="100%" class="max-w-auto" height="auto" src="{{ $img }}" />
|
|
||||||
@elseif($lesson_details->lesson_type == 'vimeo-url' && $lesson_details->video_type == 'vimeo')
|
|
||||||
@php
|
|
||||||
$video_url = $lesson_details->lesson_src;
|
|
||||||
$video_id = explode('https://vimeo.com/', $video_url);
|
|
||||||
$video_id = str_replace('https://vimeo.com/', '', $video_url);
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="course-video-area border-primary border">
|
|
||||||
<!-- Video -->
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<div id="player">
|
|
||||||
<iframe height="500" src="https://player.vimeo.com/video/{{ $video_id }}?loop=false&byline=false&portrait=false&title=false&speed=true&transparent=0&gesture=media" allowfullscreen allowtransparency allow="autoplay"></iframe>
|
|
||||||
@include('course_player.player_config')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif($lesson_details->lesson_type == 'google_drive')
|
|
||||||
@php
|
|
||||||
$video_url = $lesson_details->lesson_src;
|
|
||||||
$url_array_1 = explode('/', $video_url . '/');
|
|
||||||
$url_array_2 = explode('=', $video_url);
|
|
||||||
$video_id = null;
|
|
||||||
if ($url_array_1[4] == 'd'):
|
|
||||||
$video_id = $url_array_1[5];
|
|
||||||
else:
|
|
||||||
$video_id = $url_array_2[1];
|
|
||||||
endif;
|
|
||||||
@endphp
|
|
||||||
<div class="course-video-area border-primary border">
|
|
||||||
<!-- Video -->
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<video width="100%" height="680" id="player" playsinline controls>
|
|
||||||
<source class="" src="https://www.googleapis.com/drive/v3/files/{{ $video_id }}?alt=media&key={{ get_settings('youtube_api_key') }}" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
@include('course_player.player_config')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif($lesson_details->lesson_type == 'html5')
|
|
||||||
<div class="course-video-area border-primary border">
|
|
||||||
<!-- Video -->
|
|
||||||
<div class="course-video-wrap">
|
|
||||||
<video width="100%" height="680" id="player" playsinline controls>
|
|
||||||
<source class="remove_video_src" src="{{ $lesson_details->lesson_src }}" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
@include('course_player.player_config')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@elseif($lesson_details->lesson_type == 'document_type')
|
|
||||||
@php
|
|
||||||
$src = route('course.get_file', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id])
|
|
||||||
@endphp
|
|
||||||
@if ($lesson_details->attachment_type == 'pdf')
|
|
||||||
{{-- <iframe class="embed-responsive-item" width="100%" src="{{ $src }}" allowfullscreen></iframe> --}}
|
|
||||||
|
|
||||||
<iframe class="embed-responsive-item" width="100%" height="600px" src="{{ route('pdf_canvas', ['course_id' => $lesson_details->course_id, 'lesson_id' => $lesson_details->id]) }}" allowfullscreen></iframe>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@elseif($lesson_details->attachment_type == 'doc' || $lesson_details->attachment_type == 'ppt')
|
|
||||||
<iframe class="embed-responsive-item" width='100%' src="https://view.officeapps.live.com/op/embed.aspx?src={{ $src }}" frameborder='0'></iframe>
|
|
||||||
@elseif($lesson_details->attachment_type == 'txt')
|
|
||||||
<iframe class="embed-responsive-item" width='100%' src="{{ $src }}" frameborder='0'></iframe>
|
|
||||||
@endif
|
|
||||||
@elseif($lesson_details->lesson_type == 'quiz')
|
|
||||||
<div class="course-video-area border-primary pb-5">
|
|
||||||
@include('course_player.quiz.index')
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<iframe class="embed-responsive-item" width="100%" src="{{ $lesson_details->lesson_src }}" allowfullscreen></iframe>
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Disable right-click on video
|
|
||||||
document.getElementById('player').oncontextmenu = function() {
|
|
||||||
return false; // Prevent right-click menu
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@ -1,166 +0,0 @@
|
|||||||
<style>
|
|
||||||
.serial {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
background: #F2F3F5;
|
|
||||||
border-radius: 30px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.fill-text-note {
|
|
||||||
color: #4b5675
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
@php
|
|
||||||
$lesson_history = App\Models\Watch_history::where('course_id', $course_details->id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->firstOrNew();
|
|
||||||
$completed_lesson_arr = json_decode($lesson_history->completed_lesson, true);
|
|
||||||
$completed_lesson_arr = is_array($completed_lesson_arr) ? $completed_lesson_arr : array();
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<form action="{{ route('quiz.submit', $quiz->id) }}" method="post" class="quiz-submit-form">@csrf
|
|
||||||
<input type="hidden" name="quiz_id" value="{{ $quiz->id }}">
|
|
||||||
@foreach ($questions as $key => $question)
|
|
||||||
<div class="question px-4 mb-4 @if ($key > 0) d-none @endif">
|
|
||||||
<div class="mb-3 d-flex gap-3">
|
|
||||||
<span class="serial">{{ ++$key }} </span>
|
|
||||||
@if($question->type == 'fill_blanks')
|
|
||||||
<div>
|
|
||||||
@php
|
|
||||||
$correct_answers = json_decode($question['answer'], true);
|
|
||||||
$question_title = remove_js(htmlspecialchars_decode_($question['title']));
|
|
||||||
foreach($correct_answers as $correct_answer):
|
|
||||||
$question_title = str_replace($correct_answer, ' _____ ', $question_title);
|
|
||||||
endforeach;
|
|
||||||
@endphp
|
|
||||||
{{ $question_title; }}
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div>{!! $question->title !!}</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row gap-0">
|
|
||||||
@if ($question->type == 'mcq')
|
|
||||||
@php $options = json_decode($question->options, true) ?? []; @endphp
|
|
||||||
@foreach ($options as $index => $option)
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<input class="form-check-input" type="checkbox" name="{{ $question->id }}[]"
|
|
||||||
value="{{ $option }}" id="{{ $option }}-{{ $question->id }}">
|
|
||||||
<label class="form-check-label text-capitalize"
|
|
||||||
for="{{ $option }}-{{ $question->id }}">{{ $option }}</label>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
@elseif($question->type == 'fill_blanks')
|
|
||||||
<input type="text" class="form-control tagify" name="{{ $question->id }}" data-role="tagsinput">
|
|
||||||
<small class="fill-text-note">{{ get_phrase('You can keep multiple answers. Just put your answer and hit enter.') }}</small>
|
|
||||||
@elseif($question->type == 'true_false')
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<input class="form-check-input" type="radio" name="{{ $question->id }}" value="true"
|
|
||||||
id="question-{{ $question->id }}-true">
|
|
||||||
<label class="form-check-label"
|
|
||||||
for="question-{{ $question->id }}-true">{{ get_phrase('True') }}</label>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-2">
|
|
||||||
<input class="form-check-input" type="radio" name="{{ $question->id }}" value="false"
|
|
||||||
id="question-{{ $question->id }}-false">
|
|
||||||
<label class="form-check-label"
|
|
||||||
for="question-{{ $question->id }}-false">{{ get_phrase('False') }}</label>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
@if ($questions->count() > 0)
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12 d-flex gap-3 justify-content-center">
|
|
||||||
<button type="button" class="eBtn gradient border-0" id="prevBtn" onclick="prevQuestion()"><i
|
|
||||||
class="fi fi-rr-angle-small-left"></i>{{ get_phrase('Prev') }}</button>
|
|
||||||
<button type="button" class="eBtn gradient border-0" id="nextBtn"
|
|
||||||
onclick="nextQuestion()">{{ get_phrase('Next') }}<i class="fi fi-rr-angle-small-right"></i></button>
|
|
||||||
@if ($submits->count() < $quiz->retake)
|
|
||||||
<button type="button" class="eBtn gradient border-0 d-none" id="submitBtn"
|
|
||||||
onclick="submitQuiz()">{{ get_phrase('Submit') }}<i class="fi fi-rr-badge-check ms-2"></i></button>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
@include('course_player.init')
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let nextBtn = document.querySelector('#nextBtn');
|
|
||||||
let prevBtn = document.querySelector('#prevBtn');
|
|
||||||
let submitBtn = document.querySelector('#submitBtn');
|
|
||||||
let submitForm = document.querySelector('.quiz-submit-form');
|
|
||||||
let questions = document.querySelectorAll('.question');
|
|
||||||
|
|
||||||
// Initialize buttons visibility
|
|
||||||
if (questions.length === 1) {
|
|
||||||
nextBtn.classList.add('d-none'); // Hide Next button
|
|
||||||
submitBtn.classList.remove('d-none'); // Show Submit button
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next question
|
|
||||||
function nextQuestion() {
|
|
||||||
let selectQuestion = document.querySelector('.question:not(.d-none)');
|
|
||||||
let nextQuestion = selectQuestion.nextElementSibling;
|
|
||||||
if (nextQuestion && nextQuestion.classList.contains('question')) {
|
|
||||||
selectQuestion.classList.add('d-none');
|
|
||||||
nextQuestion.classList.remove('d-none');
|
|
||||||
}
|
|
||||||
let nextNextQuestion = nextQuestion ? nextQuestion.nextElementSibling : null;
|
|
||||||
if (!(nextNextQuestion && nextNextQuestion.classList.contains('question'))) {
|
|
||||||
submitBtn.classList.remove('d-none');
|
|
||||||
nextBtn.classList.add('d-none');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Previous question
|
|
||||||
function prevQuestion() {
|
|
||||||
let selectQuestion = document.querySelector('.question:not(.d-none)');
|
|
||||||
let prevQuestion = selectQuestion.previousElementSibling;
|
|
||||||
if (prevQuestion && prevQuestion.classList.contains('question')) {
|
|
||||||
selectQuestion.classList.add('d-none');
|
|
||||||
prevQuestion.classList.remove('d-none');
|
|
||||||
}
|
|
||||||
if (nextBtn.classList.contains('d-none')) {
|
|
||||||
nextBtn.classList.remove('d-none');
|
|
||||||
submitBtn.classList.add('d-none');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Submit quiz
|
|
||||||
function submitQuiz() {
|
|
||||||
|
|
||||||
var quizId = "{{ $quiz->id }}";
|
|
||||||
var completed_lesson_arr = @json($completed_lesson_arr); // Convert the PHP array to a JavaScript array
|
|
||||||
|
|
||||||
// Check if quizId is in the completed_lesson_arr array using JavaScript's `includes()` method
|
|
||||||
if (!completed_lesson_arr.includes(quizId)) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('set.watch.history') }}", // Your route
|
|
||||||
type: "post",
|
|
||||||
data: {
|
|
||||||
lesson_id: "{{ $quiz->id }}",
|
|
||||||
course_id: "{{ $course_details->id }}"
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
submitForm.submit();
|
|
||||||
},
|
|
||||||
error: function(xhr, status, error) {
|
|
||||||
console.error("Error updating watch history:", xhr.responseText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
submitForm.submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@ -1,145 +0,0 @@
|
|||||||
@php
|
|
||||||
$sections = App\Models\Section::where('course_id', $course_details->id)
|
|
||||||
->orderBy('sort')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
$completed_lesson = json_decode(
|
|
||||||
App\Models\Watch_history::where('course_id', $course_details->id)
|
|
||||||
->where('student_id', Auth()->user()->id)
|
|
||||||
->value('completed_lesson'),
|
|
||||||
true,
|
|
||||||
) ?? [];
|
|
||||||
$active_section = App\Models\Lesson::where('id', $lesson_details->id ?? '')->value('section_id');
|
|
||||||
|
|
||||||
$lesson_history = App\Models\Watch_history::where('course_id', $course_details->id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->firstOrNew();
|
|
||||||
$completed_lesson_arr = json_decode($lesson_history->completed_lesson, true);
|
|
||||||
$completed_lesson_arr = is_array($completed_lesson_arr) ? $completed_lesson_arr : array();
|
|
||||||
$complated_lesson = is_array($completed_lesson_arr) ? count($completed_lesson_arr) : 0;
|
|
||||||
$course_progress_out_of_100 = progress_bar($course_details->id);
|
|
||||||
|
|
||||||
$user_id = Auth()->user()->id;
|
|
||||||
$is_course_instructor = is_course_instructor($course_details->id, $user_id);
|
|
||||||
|
|
||||||
$is_locked = 0;
|
|
||||||
$locked_lesson_ids = array();
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.checkbox-icon {
|
|
||||||
color: #754ffe;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="course-content-playlist">
|
|
||||||
<div class="row border-bottom pb-3">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h1 class="heading mb-2">{{ get_phrase('Course curriculum') }}</h1>
|
|
||||||
<p class="info text-14px text-center mb-1">{{ $course_progress_out_of_100 }}% {{ get_phrase('Completed') }}
|
|
||||||
({{ $complated_lesson }}/{{ lesson_count($course_details->id) }})
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="course-playlist-accordion">
|
|
||||||
<div class="accordion" id="coursePlay">
|
|
||||||
@foreach ($sections as $section)
|
|
||||||
@php
|
|
||||||
$lessons = App\Models\Lesson::where('section_id', $section->id)
|
|
||||||
->orderBy('sort')
|
|
||||||
->get();
|
|
||||||
@endphp
|
|
||||||
<div class="accordion-item">
|
|
||||||
<h2 class="accordion-header">
|
|
||||||
<button class="accordion-button @if ($active_section != $section->id) collapsed @endif" type="button" data-bs-toggle="collapse" data-bs-target="#collapse_{{ $section->id }}" aria-expanded="@if ($section->id != $active_section) false @else true @endif" aria-controls="collapse_{{ $section->id }}">
|
|
||||||
{{ ucfirst($section->title) }}
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="collapse_{{ $section->id }}" class="accordion-collapse collapse @if ($section->id == $active_section) show @endif" data-bs-parent="#coursePlay">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<ul class="coourse-playlist-list">
|
|
||||||
@foreach ($lessons as $key => $lesson)
|
|
||||||
@php $type = $lesson->lesson_type; @endphp
|
|
||||||
<li class="coourse-playlist-item @if (isset($history->watching_lesson_id) && $lesson->id == $history->watching_lesson_id || $lesson->id == $lesson_details->id) active @else lock @endif">
|
|
||||||
<div class="check-title-area align-items-center">
|
|
||||||
@if($course_details->enable_drip_content)
|
|
||||||
@if($is_locked)
|
|
||||||
<i class="fas fa-lock" title="<?php echo get_phrase('Complete previous lesson to unlock it'); ?>"></i>
|
|
||||||
@else
|
|
||||||
@if(in_array($lesson->id, $completed_lesson_arr))
|
|
||||||
<i class="fas fa-check-circle checkbox-icon" title="<?php echo get_phrase('Lesson completed'); ?>"></i>
|
|
||||||
@elseif(in_array($type, ['video-url', 'system-video', 'vimeo-url', 'google_drive']))
|
|
||||||
<i class="form-check-input flexCheckChecked mt-0" title="<?php echo get_phrase('Play Now'); ?>"></i>
|
|
||||||
@else
|
|
||||||
<input class="form-check-input flexCheckChecked mt-0" @if (in_array($lesson->id, $completed_lesson)) checked @endif type="checkbox" id="{{ $lesson->id }}">
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
<div class="play-lock-number">
|
|
||||||
<span>
|
|
||||||
@if (in_array($type, ['text', 'document_type', 'iframe']))
|
|
||||||
<i class="fa-solid fa-file"></i>
|
|
||||||
@elseif (in_array($type, ['video-url', 'system-video', 'vimeo-url']))
|
|
||||||
<i class="fa-solid fa-video"></i>
|
|
||||||
@elseif ($type == 'image')
|
|
||||||
<i class="fa-solid fa-image"></i>
|
|
||||||
@elseif ($type == 'google_drive')
|
|
||||||
<i class="fa-brands fa-google-drive"></i>
|
|
||||||
@else
|
|
||||||
<i class="fa-solid fa-file"></i>
|
|
||||||
@endif
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p class="d-none">{{ $lesson->lesson_type }}</p>
|
|
||||||
<a href="{{ route('course.player', ['slug' => $course_details->slug, 'id' => $lesson->id]) }}" class="video-title">{{ $lesson->title }}</a>
|
|
||||||
@else
|
|
||||||
<input class="form-check-input flexCheckChecked mt-0" @if (in_array($lesson->id, $completed_lesson)) checked @endif type="checkbox" id="{{ $lesson->id }}">
|
|
||||||
<div class="play-lock-number">
|
|
||||||
@php $type = $lesson->lesson_type; @endphp
|
|
||||||
<span>
|
|
||||||
@if (in_array($type, ['text', 'document_type', 'iframe']))
|
|
||||||
<i class="fa-solid fa-file"></i>
|
|
||||||
@elseif (in_array($type, ['video-url', 'system-video', 'vimeo-url']))
|
|
||||||
<i class="fa-solid fa-video"></i>
|
|
||||||
@elseif ($type == 'image')
|
|
||||||
<i class="fa-solid fa-image"></i>
|
|
||||||
@elseif ($type == 'google_drive')
|
|
||||||
<i class="fa-brands fa-google-drive"></i>
|
|
||||||
@else
|
|
||||||
<i class="fa-solid fa-file"></i>
|
|
||||||
@endif
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<p class="d-none">{{ $lesson->lesson_type }}</p>
|
|
||||||
<a href="{{ route('course.player', ['slug' => $course_details->slug, 'id' => $lesson->id]) }}" class="video-title">{{ $lesson->title }}</a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (lesson_durations($lesson->id) != '00:00:00')
|
|
||||||
<p class="duration">{{ lesson_durations($lesson->id) }}</p>
|
|
||||||
@endif
|
|
||||||
</li>
|
|
||||||
@php
|
|
||||||
if ($is_locked) {
|
|
||||||
$locked_lesson_ids[] = $lesson->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!in_array($lesson->id, $completed_lesson_arr) &&
|
|
||||||
!$is_locked &&
|
|
||||||
$course_details->enable_drip_content == 1 &&
|
|
||||||
auth()->user() && // Lowercase 'auth()' for consistency
|
|
||||||
!$is_course_instructor
|
|
||||||
) {
|
|
||||||
$is_locked = 1;
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
@extends('layouts.default')
|
|
||||||
@push('title', get_phrase('Bootcamps'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div class="eNtry-breadcum">
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">{{ get_phrase('Home') }}</a></li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">{{ get_phrase(' Article') }}</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<h1 class="showing-text mt-15"></h1>
|
|
||||||
</div>
|
|
||||||
<div class="">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-8 ">
|
|
||||||
<h3 class="g-title">{{$article->topic_name}}</h3>
|
|
||||||
<p class=" mt-3 mb-3 overflow-auto">{!! $article->description !!}</p>
|
|
||||||
<hr>
|
|
||||||
<span class="showing-text pe-3">{{get_phrase(' Share On :')}}</span>
|
|
||||||
@if (get_frontend_settings('twitter') != '')
|
|
||||||
<a href="{{ get_frontend_settings('twitter') }}">
|
|
||||||
<i class="fa-brands fa-twitter pe-3"></i>
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
@if (get_frontend_settings('linkedin') != '')
|
|
||||||
<a href="{{ get_frontend_settings('linkedin') }}">
|
|
||||||
<i class="fa-brands fa-linkedin pe-3"></i>
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
@if (get_frontend_settings('facebook') != '')
|
|
||||||
<a href="{{ get_frontend_settings('facebook') }}">
|
|
||||||
<i class="fa-brands fa-square-facebook pe-3"></i>
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col-sm-12 col-md-4">
|
|
||||||
<div class="shadow-sm p-4 rounded-3">
|
|
||||||
<div class="m-3">
|
|
||||||
@php
|
|
||||||
$topicks = App\Models\Knowledge_base_topick::where('knowledge_base_id', $title->id)->orderBy('updated_at', 'desc')->get();
|
|
||||||
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<h3 class="showing-text pb-3">{{ ucwords($title->title) }}</h3>
|
|
||||||
@foreach($topicks as $topic)
|
|
||||||
<h4 ><a class="text-decoration-underline {{$article->id == $topic->id ? 'text-primary' : '' }}" href="{{route('knowledge.base.article', ['id'=> $topic->id])}}">{{ucwords($topic->topic_name)}}</a></h4>
|
|
||||||
<hr>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
@push('js')@endpush
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
@extends('layouts.default')
|
|
||||||
@push('title', get_phrase('Bootcamps'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<section class="breadcum-area">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div class="eNtry-breadcum">
|
|
||||||
<nav aria-label="breadcrumb">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item"><a href="{{ route('home') }}">{{ get_phrase('Home') }}</a></li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">{{ get_phrase(' Knowledge Base') }}</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
<h3 class="g-title">{{ get_phrase(' Knowledge Base') }}</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<div class="eNtery-item d-flex h-100">
|
|
||||||
<div class="container " >
|
|
||||||
<div class=" row" >
|
|
||||||
<div class=" col-sm-12 col-md-6 " >
|
|
||||||
@foreach($articles as $index => $article)
|
|
||||||
@php
|
|
||||||
|
|
||||||
$devided_val = (count($articles) / 2) - 1;
|
|
||||||
|
|
||||||
if($index > $devided_val){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@endphp
|
|
||||||
<div class="accordion" id="accordionExample-{{ $index }}">
|
|
||||||
<div class=" mb-3 p-3 sidebar">
|
|
||||||
<div class="accordion-item ">
|
|
||||||
<h2 class="accordion-header" id="heading-{{ $index }}">
|
|
||||||
<button class="accordion-button p-3 @if($index !== 0) collapsed @endif" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-{{ $index }}" aria-expanded="{{ $index === 0 ? 'true' : 'false' }}" aria-controls="collapse-{{ $index }}">{{ ucwords($article->title) }}
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="collapse-{{ $index }}" class="accordion-collapse collapse @if($index === 0) show @endif" aria-labelledby="heading-{{ $index }}" data-bs-parent="#accordionExample-{{ $index }}">
|
|
||||||
<div class="accordion-body">
|
|
||||||
@php
|
|
||||||
$topics = App\Models\Knowledge_base_topick::where('knowledge_base_id', $article->id)->orderBy('updated_at', 'desc')->get();
|
|
||||||
@endphp
|
|
||||||
<ul>
|
|
||||||
@foreach($topics as $key => $topic)
|
|
||||||
<li class="topic-name" id="topic-name-{{$key}}">
|
|
||||||
<a href="{{ route('knowledge.base.article', ['id' => $topic->id]) }}">
|
|
||||||
{{ ucwords($topic->topic_name) }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<hr>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
<div class=" col-sm-12 col-md-6 " >
|
|
||||||
@foreach($articles as $index => $article)
|
|
||||||
@php
|
|
||||||
|
|
||||||
$devided_val = (count($articles) / 2) - 1;
|
|
||||||
|
|
||||||
if($index <= $devided_val){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
@endphp
|
|
||||||
<div class="accordion" id="accordionExample-{{ $index }}">
|
|
||||||
<div class=" mb-3 p-3 sidebar">
|
|
||||||
<div class="accordion-item ">
|
|
||||||
<h2 class="accordion-header" id="heading-{{ $index }}">
|
|
||||||
<button class="accordion-button p-3 @if($index !== 0) collapsed @endif" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-{{ $index }}" aria-expanded="{{ $index === 0 ? 'true' : 'false' }}" aria-controls="collapse-{{ $index }}">{{ ucwords($article->title) }}
|
|
||||||
</button>
|
|
||||||
</h2>
|
|
||||||
<div id="collapse-{{ $index }}" class="accordion-collapse collapse @if($index === 0) show @endif" aria-labelledby="heading-{{ $index }}" data-bs-parent="#accordionExample-{{ $index }}">
|
|
||||||
<div class="accordion-body">
|
|
||||||
@php
|
|
||||||
$topics = App\Models\Knowledge_base_topick::where('knowledge_base_id', $article->id)->orderBy('updated_at', 'desc')->get();
|
|
||||||
@endphp
|
|
||||||
<ul>
|
|
||||||
@foreach($topics as $key => $topic)
|
|
||||||
<li class="topic-name" id="topic-name-{{$key}}">
|
|
||||||
<a href="{{ route('knowledge.base.article', ['id' => $topic->id]) }}">
|
|
||||||
{{ ucwords($topic->topic_name) }}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<hr>
|
|
||||||
@endforeach
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
{{$articles->links()}}
|
|
||||||
</div>
|
|
||||||
@if ($articles->count() == 0)
|
|
||||||
<div class="col-12 bg-white radius-10 py-5">
|
|
||||||
@include('frontend.default.empty')
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{-- <script>
|
|
||||||
const topicName =document.querySelectorAll('.topic-name');
|
|
||||||
for(let i = 0; i < topicName.length; i++){
|
|
||||||
const topicNameId =document.querySelectorAll(`#topic-name-${i}`);
|
|
||||||
|
|
||||||
|
|
||||||
} for(let v =0; v < topicNameId.length; v++){
|
|
||||||
console.log(v)
|
|
||||||
|
|
||||||
}
|
|
||||||
</script> --}}
|
|
||||||
|
|
||||||
|
|
||||||
@endsection
|
|
||||||
@push('js')@endpush
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function wishlistToggle(course_id, elem) {
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: "{{ route('toggleWishItem') }}" + '/' + course_id,
|
|
||||||
success: function(response) {
|
|
||||||
if (response) {
|
|
||||||
if (response.toggleStatus == 'added') {
|
|
||||||
$(elem).addClass('inList');
|
|
||||||
|
|
||||||
$(elem).attr('data-bs-title', '{{get_phrase('Remove from wishlist')}}')
|
|
||||||
.tooltip('dispose')
|
|
||||||
.tooltip('show');
|
|
||||||
|
|
||||||
success('{{ get_phrase('This course added to your wishlist') }}');
|
|
||||||
|
|
||||||
} else if (response.toggleStatus == 'removed') {
|
|
||||||
$(elem).removeClass('inList');
|
|
||||||
|
|
||||||
$(elem).attr('data-bs-title', '{{get_phrase('Add to wishlist')}}')
|
|
||||||
.tooltip('dispose')
|
|
||||||
.tooltip('show');
|
|
||||||
|
|
||||||
success('{{ get_phrase('This course removed from your wishlist') }}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function() {
|
|
||||||
//When need to add a wishlist button inside a anchor tag
|
|
||||||
$('.checkPropagation').on('click', function(event) {
|
|
||||||
var action = $(this).attr('action');
|
|
||||||
var onclickFunction = $(this).attr('onclick');
|
|
||||||
var onChange = $(this).attr('onchange');
|
|
||||||
var tag = $(this).prop("tagName").toLowerCase();
|
|
||||||
console.log(tag);
|
|
||||||
if (tag != 'a' && action) {
|
|
||||||
$(location).attr('href', $(this).attr('action'));
|
|
||||||
return false;
|
|
||||||
} else if (onclickFunction) {
|
|
||||||
if (onclickFunction) {
|
|
||||||
onclickFunction;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else if (tag == 'a') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// change course layout grid and list in course page
|
|
||||||
$('.layout').on('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
let layout = $(this).attr('id');
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: "{{ route('change.layout') }}",
|
|
||||||
data: {
|
|
||||||
view: layout
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
if (response.reload) {
|
|
||||||
window.location.reload(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// toggleWishItems
|
|
||||||
$('.toggleWishItem').on('click', function(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let get_item_id = $(this).attr('id');
|
|
||||||
let item_id = get_item_id.split('-');
|
|
||||||
item_id = item_id[1];
|
|
||||||
|
|
||||||
const $this = $(this);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: "get",
|
|
||||||
url: "{{ route('toggleWishItem') }}" + '/' + item_id,
|
|
||||||
success: function(response) {
|
|
||||||
if (response) {
|
|
||||||
if (response.toggleStatus == 'added') {
|
|
||||||
$this.addClass('inList');
|
|
||||||
} else if (response.toggleStatus == 'removed') {
|
|
||||||
$this.removeClass('inList');
|
|
||||||
}
|
|
||||||
window.location.reload(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
if ($('.tagify:not(.inited)').length) {
|
|
||||||
var tagify = new Tagify(document.querySelector('.tagify:not(.inited)'), {
|
|
||||||
placeholder: '{{ get_phrase('Enter your keywords') }}',
|
|
||||||
delimiters: "~",
|
|
||||||
})
|
|
||||||
$('.tagify:not(.inited)').addClass('inited');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
||||||
|
|
||||||
|
|
||||||
//Overlap content start
|
|
||||||
document.querySelectorAll('.overlay-content').forEach(function(elem){
|
|
||||||
overlayCollapse(elem);
|
|
||||||
});
|
|
||||||
|
|
||||||
function overlayCollapse(elem){
|
|
||||||
if (elem.classList.contains('show-more')) {
|
|
||||||
elem.classList.add('show-less');
|
|
||||||
elem.classList.remove('show-more');
|
|
||||||
elem.querySelector('p a.overlay-action').textContent = "{{get_phrase('Show less')}} - ";
|
|
||||||
} else if (elem.classList.contains('show-less')) {
|
|
||||||
elem.classList.add('show-more');
|
|
||||||
elem.classList.remove('show-less');
|
|
||||||
elem.querySelector('p a.overlay-action').textContent = "{{get_phrase('Show more')}} + ";
|
|
||||||
} else {
|
|
||||||
elem.classList.add('show-more');
|
|
||||||
elem.insertAdjacentHTML('beforeend', '<p><a href="javascript:;" class="overlay-action title text-14px">{{get_phrase("Show more")}} + </a></p>');
|
|
||||||
|
|
||||||
// Select the newly added element and attach the event listener
|
|
||||||
elem.querySelector('p a.overlay-action').addEventListener('click', function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
overlayCollapse(elem);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Overlap content ended
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
$.ajaxSetup({
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('.gSearch-icon').on('click', function() {
|
|
||||||
$('.gSearch-show').toggleClass('active');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@ -1,159 +0,0 @@
|
|||||||
@extends('layouts.default')
|
|
||||||
@push('title', get_phrase('My courses'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<section class="my-course-content">
|
|
||||||
<div class="profile-banner-area"></div>
|
|
||||||
<div class="container profile-banner-area-container">
|
|
||||||
<div class="row">
|
|
||||||
@include('frontend.default.student.left_sidebar')
|
|
||||||
|
|
||||||
<div class="col-lg-9 px-4">
|
|
||||||
<h4 class="g-title">{{ get_phrase('My Courses') }}</h4>
|
|
||||||
<div class="row mt-5">
|
|
||||||
@foreach ($my_courses as $course)
|
|
||||||
@php
|
|
||||||
$course_progress = progress_bar($course->course_id);
|
|
||||||
@endphp
|
|
||||||
<div class="col-lg-4 col-md-4 col-sm-6 mb-30">
|
|
||||||
<div class="card Ecard g-card c-card">
|
|
||||||
<div class="card-head">
|
|
||||||
<img src="{{ get_image($course->thumbnail) }}" alt="course-thumbnail">
|
|
||||||
</div>
|
|
||||||
<div class="card-body entry-details">
|
|
||||||
<div class="info-card mb-15">
|
|
||||||
<div class="creator">
|
|
||||||
<img src="{{ get_image($course->user_photo) }}" alt="author-image">
|
|
||||||
<h5>{{ $course->user_name }}</h5>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="entry-title">
|
|
||||||
<a href="{{ route('course.details', $course->slug) }}">
|
|
||||||
<h3 class="w-100 ellipsis-line-2">{{ ucfirst($course->title) }}</h3>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="single-progress">
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-10">
|
|
||||||
<h5>{{ get_phrase('Progress') }}</h5>
|
|
||||||
<p>{{ $course_progress }}%</p>
|
|
||||||
</div>
|
|
||||||
<div class="progress" role="progressbar" aria-label="Basic example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
|
||||||
<div class="progress-bar" style="width: {{ $course_progress }}%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="class-details pt-3">
|
|
||||||
<div class="d-flex gap-3 justify-content-between">
|
|
||||||
@if($course->expiry_date > 0 && $course->expiry_date < time())
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="text-capitalize">
|
|
||||||
{{ get_phrase('Expired') }}:
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="badge bg-danger text-capitalize">
|
|
||||||
{{ date('d M Y, H:i A', $course->expiry_date) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@if($course->expiry_date == 0)
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="text-capitalize">
|
|
||||||
{{ get_phrase('Expiry period') }}:
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="badge bg-success text-capitalize">
|
|
||||||
{{ get_phrase('Lifetime Access') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="text-capitalize">
|
|
||||||
{{ get_phrase('Expiration On') }}:
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="class-status">
|
|
||||||
<span class="badge bg-success text-capitalize">
|
|
||||||
{{ date('d M Y, H:i A', $course->expiry_date) }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@php
|
|
||||||
$watch_history = App\Models\Watch_history::where('course_id', $course->course_id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
$lesson = App\Models\Lesson::where('course_id', $course->course_id)
|
|
||||||
->orderBy('sort', 'asc')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (!$watch_history && !$lesson) {
|
|
||||||
$url = route('course.player', ['slug' => $course->slug]);
|
|
||||||
} else {
|
|
||||||
if ($watch_history) {
|
|
||||||
$lesson_id = $watch_history->watching_lesson_id;
|
|
||||||
} elseif ($lesson) {
|
|
||||||
$lesson_id = $lesson->id;
|
|
||||||
}
|
|
||||||
$url = route('course.player', ['slug' => $course->slug, 'id' => $lesson_id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
@if($course->expiry_date > 0 && $course->expiry_date < time())
|
|
||||||
<a href="{{ route('purchase.course', ['course_id' => $course->course_id]) }}" class="eBtn learn-btn w-100 text-center mt-20 f-500">
|
|
||||||
{{ get_phrase('Renew') }}
|
|
||||||
</a>
|
|
||||||
@else
|
|
||||||
@if ($course_progress > 0 && $course_progress < 100.00)
|
|
||||||
<a href="{{ $url }}" class="eBtn learn-btn w-100 text-center mt-20 f-500">
|
|
||||||
{{ get_phrase('Continue') }}
|
|
||||||
</a>
|
|
||||||
@elseif ($course_progress == 100.00)
|
|
||||||
<a href="{{ $url }}" class="eBtn learn-btn w-100 text-center mt-20 f-500">
|
|
||||||
{{ get_phrase('Watch again') }}
|
|
||||||
</a>
|
|
||||||
@else
|
|
||||||
<a href="{{ $url }}" class="eBtn learn-btn w-100 text-center mt-20 f-500">
|
|
||||||
{{ get_phrase('Start Now') }}
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
@endif
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endforeach
|
|
||||||
@if ($my_courses->count() == 0)
|
|
||||||
<div class="row bg-white radius-10">
|
|
||||||
<div class="com-md-12">
|
|
||||||
@include('frontend.default.empty')
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
@if (count($my_courses) > 0)
|
|
||||||
<div class="entry-pagination">
|
|
||||||
<nav aria-label="Page navigation example">
|
|
||||||
{{ $my_courses->links() }}
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
<!-- Pagination -->
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<!------------ My wishlist area End ------------>
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
@endpush
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
@extends('layouts.default')
|
|
||||||
@push('title', get_phrase('My profile'))
|
|
||||||
@push('meta')@endpush
|
|
||||||
@push('css')@endpush
|
|
||||||
@section('content')
|
|
||||||
<!------------ My profile area start ------------>
|
|
||||||
<section class="course-content">
|
|
||||||
<div class="profile-banner-area"></div>
|
|
||||||
<div class="container profile-banner-area-container">
|
|
||||||
<div class="row">
|
|
||||||
@include('frontend.default.student.left_sidebar')
|
|
||||||
<div class="col-lg-9">
|
|
||||||
|
|
||||||
<div class="my-panel message-panel edit_profile mb-4">
|
|
||||||
<h4 class="g-title mb-5">{{ get_phrase('Personal Information') }}</h4>
|
|
||||||
<form action="{{ route('update.profile', $user_details->id) }}" method="POST">@csrf
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="name" class="form-label">{{ get_phrase('Full Name') }}</label>
|
|
||||||
<input type="text" class="form-control" name="name" value="{{ $user_details->name }}" id="name">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="email" class="form-label">{{ get_phrase('Email Address') }}</label>
|
|
||||||
<input type="email" class="form-control" name="email" value="{{ $user_details->email }}" id="email">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="phone" class="form-label">{{ get_phrase('Phone Number') }}</label>
|
|
||||||
<input type="tel" class="form-control" name="phone" value="{{ $user_details->phone }}" id="phone">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="website" class="form-label">{{ get_phrase('Website') }}</label>
|
|
||||||
<input type="text" class="form-control" name="website" value="{{ $user_details->website }}" id="website">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="facebook" class="form-label">{{ get_phrase('Facebook') }}</label>
|
|
||||||
<input type="text" class="form-control" name="facebook" value="{{ $user_details->facebook }}" id="facebook">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="twitter" class="form-label">{{ get_phrase('Twitter') }}</label>
|
|
||||||
<input type="text" class="form-control" name="twitter" value="{{ $user_details->twitter }}" id="twitter">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-6 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="linkedin" class="form-label">{{ get_phrase('Linkedin') }}</label>
|
|
||||||
<input type="text" class="form-control" name="linkedin" value="{{ $user_details->linkedin }}" id="linkedin">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="skills" class="form-label">{{ get_phrase('Skills') }}</label>
|
|
||||||
<input type="text" class="form-control tagify" name="skills" data-role="tagsinput" value="{{ $user_details->skills }}" id="skills">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="biography" class="form-label">{{ get_phrase('Biography') }}</label>
|
|
||||||
<textarea name="biography" class="form-control" id="biography" cols="30" rows="5">{{ $user_details->biography }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="eBtn btn gradient mt-10">{{ get_phrase('Save Changes') }}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="my-panel message-panel edit_profile">
|
|
||||||
<h4 class="g-title mb-5">{{ get_phrase('Change Password') }}</h4>
|
|
||||||
<form action="{{ route('password.change') }}" method="POST">@csrf
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">{{ get_phrase('Current password') }}</label>
|
|
||||||
<input type="password" class="form-control" name="current_password" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">{{ get_phrase('New password') }}</label>
|
|
||||||
<input type="password" class="form-control" name="new_password" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-lg-12 mb-20">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="form-label">{{ get_phrase('Confirm password') }}</label>
|
|
||||||
<input type="password" class="form-control" name="confirm_password" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button class="eBtn btn gradient mt-10">{{ get_phrase('Update password') }}</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<!------------ My profile area end ------------>
|
|
||||||
@endsection
|
|
||||||
@push('js')
|
|
||||||
|
|
||||||
@endpush
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
|
|
||||||
@php
|
|
||||||
$seo_meta_tag = App\Models\SeoField::where('bootcamp_id', $bootcamp_details->id)->firstOrNew();
|
|
||||||
@endphp
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="meta_title" class="form-label ol-form-label">{{ get_phrase('Meta Title') }}</label>
|
|
||||||
<input class="form-control ol-form-control" id="meta_title" name="meta_title" type="text" value="{{ $seo_meta_tag->meta_title }}" placeholder="Meta Title" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="meta_keywords" class="form-label ol-form-label">{{ get_phrase('Meta Keywords') }}</label>
|
|
||||||
<input type="text" name="meta_keywords" value="{{ $seo_meta_tag->meta_keywords }}" class="tagify ol-form-control w-100" id="meta_keywords" placeholder="Meta keywords" />
|
|
||||||
<small class="form-label ol-form-label text-muted">{{ get_phrase('Writing your keyword and hit the enter') }}</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="meta_description" class="form-label ol-form-label">{{ get_phrase('Meta Description') }}</label>
|
|
||||||
<textarea class="form-control ol-form-control" id="meta_description" name="meta_description" type="text" placeholder="Meta Description">{{ $seo_meta_tag->meta_description }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="meta_robot" class="form-label ol-form-label">{{ get_phrase('Meta Robot') }}</label>
|
|
||||||
<input class="form-control ol-form-control" id="meta_robot" name="meta_robot" type="text" value="{{ $seo_meta_tag->meta_robot }}" placeholder="Meta Robot" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="canonical_url" class="form-label ol-form-label">{{ get_phrase(' Canonical Url') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control" data-role="tagsinput" id = "canonical_url" name="canonical_url" placeholder="https://example.com/bootcamps"
|
|
||||||
value="{{ $seo_meta_tag->canonical_url }}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="custom_url" class="form-label ol-form-label">{{ get_phrase(' Custom Url') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control" data-role="tagsinput" id = "custom_url" name="custom_url" placeholder="https://example.com/dresses/bootcamps"
|
|
||||||
value="{{ $seo_meta_tag->custom_url }}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="og_title" class="form-label ol-form-label">{{ get_phrase('Og Title') }}</label>
|
|
||||||
<input type="text" class="form-control ol-form-control" data-role="tagsinput" id = "og_title" name="og_title" value="{{ $seo_meta_tag->og_title }}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="og_description" class="form-label ol-form-label">{{ get_phrase('Og Description') }}</label>
|
|
||||||
<textarea class="form-control ol-form-control" id="og_description" name="og_description" type="text">{{ $seo_meta_tag->og_description }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="og_image" class="form-label ol-form-label">{{ get_phrase('Og Image') }}</label>
|
|
||||||
<div class="og_image mb-2">
|
|
||||||
<img width="150px" src="{{ get_image($seo_meta_tag->og_image) }}" alt="....">
|
|
||||||
</div>
|
|
||||||
<input type="file" class="form-control ol-form-control" id = "og_image" name="og_image" value="{{ $seo_meta_tag->og_image }}" />
|
|
||||||
<input type="hidden" name="old_og_image" value="{{ $seo_meta_tag->og_image }}">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="json_ld" class="form-label ol-form-label">{{ get_phrase('Json Id') }}</label>
|
|
||||||
<textarea class="form-control ol-form-control" id="json_ld" name="json_ld">{{ $seo_meta_tag->json_ld }}</textarea>
|
|
||||||
</div>
|
|
||||||
@ -1,209 +0,0 @@
|
|||||||
@extends('layouts.instructor')
|
|
||||||
@push('title', get_phrase('Create course'))
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="row mb-5">
|
|
||||||
<div class="col-lg-12">
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-4 px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Add new Course') }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ol-card p-3">
|
|
||||||
<div class="ol-card-body">
|
|
||||||
<form class="ajaxForm" action="{{ route('instructor.course.store') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
<input type="hidden" name="course_type" value="general" required>
|
|
||||||
<input type="hidden" name="instructors[]" value="{{ auth()->user()->id }}" required>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6 pb-2">
|
|
||||||
<div class="eForm-layouts">
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="title">{{ get_phrase('Title') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<input type="text" name = "title" class="form-control ol-form-control" placeholder="{{ get_phrase('Enter Course Title') }}" required>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="short_description">{{ get_phrase('Short Description') }}</label>
|
|
||||||
<textarea name="short_description" placeholder="{{ get_phrase('Enter Short Description') }}" class="form-control ol-form-control" rows="5"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label" for="description">{{ get_phrase('Description') }}</label>
|
|
||||||
<textarea name="description" placeholder="{{ get_phrase('Enter Description') }}" class="form-control ol-form-control text_editor"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="eForm-layouts">
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="category_id" class="form-label ol-form-label">{{ get_phrase('Category') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<select class="ol-select2" name="category_id" id="category_id" required>
|
|
||||||
<option value="">{{ get_phrase('Select a category') }}</option>
|
|
||||||
@foreach (App\Models\Category::where('parent_id', 0)->orderBy('title', 'desc')->get() as $category)
|
|
||||||
<option value="{{ $category->id }}"> {{ $category->title }}</option>
|
|
||||||
|
|
||||||
@foreach ($category->childs as $sub_category)
|
|
||||||
<option value="{{ $sub_category->id }}"> --
|
|
||||||
{{ $sub_category->title }}
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="level" class="form-label ol-form-label">{{ get_phrase('Course level') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<select class="ol-select2" name="level" id="level" required>
|
|
||||||
<option value="">{{ get_phrase('Select your course level') }}</option>
|
|
||||||
<option value="beginner">{{ get_phrase('Beginner') }}</option>
|
|
||||||
<option value="intermediate">{{ get_phrase('Intermediate') }}</option>
|
|
||||||
<option value="advanced">{{ get_phrase('Advanced') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="language" class="form-label ol-form-label">{{ get_phrase('Made in') }}
|
|
||||||
<span class="text-danger ms-1">*</span></label>
|
|
||||||
<select class="ol-select2" name="language" id="language" required>
|
|
||||||
<option value="">{{ get_phrase('Select your course language') }}
|
|
||||||
</option>
|
|
||||||
@foreach (App\Models\Language::get() as $language)
|
|
||||||
<option value="{{ strtolower($language->name) }}" class="text-capitalize">{{ $language->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Pricing type') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" name="is_paid" value="1" class="form-check-input eRadioSuccess" id="paid" onchange="$('#paid-section').slideDown(200)" checked>
|
|
||||||
<label for="paid" class="form-check-label">{{ get_phrase('Paid') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" name="is_paid" value="0" class="form-check-input eRadioSuccess" id="free" onchange="$('#paid-section').slideUp(200)">
|
|
||||||
<label for="free" class="form-check-label">{{ get_phrase('Free') }}</label>
|
|
||||||
</div>
|
|
||||||
<div class="paid-section" id="paid-section">
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="price" class="form-label ol-form-label">{{ get_phrase('Price') }}
|
|
||||||
<small>({{ currency() }})</small><span class="text-danger ms-1">*</span></label>
|
|
||||||
|
|
||||||
<input type="number" name="price" class="form-control ol-form-control" id="price" min="1" step=".01" placeholder="{{ get_phrase('Enter your course price') }} ({{ currency() }})">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" name="discount_flag" value="1" class="form-check-input eRadioSuccess" id="discount_flag">
|
|
||||||
<label for="discount_flag" class="form-check-label">{{ get_phrase('Check if this course has discount') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label for="discounted_price" class="form-label ol-form-label">{{ get_phrase('Discounted price') }}</label>
|
|
||||||
|
|
||||||
<input type="number" name="discounted_price" class="form-control ol-form-control" id="discounted_price" min="1" step=".01" placeholder="{{ get_phrase('Enter your discount price') }} ({{ currency() }})">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Expiry period') }}</label>
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check mr-2">
|
|
||||||
<input type="radio" id="lifetime_expiry_period" name="expiry_period" class="form-check-input eRadioSuccess" value="lifetime" onchange="checkExpiryPeriod(this)" checked>
|
|
||||||
<label class="form-check-label" for="lifetime_expiry_period">{{ get_phrase('Lifetime') }}</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" id="limited_expiry_period" name="expiry_period" class="form-check-input eRadioSuccess" value="limited_time" onchange="checkExpiryPeriod(this)">
|
|
||||||
<label class="form-check-label" for="limited_expiry_period">{{ get_phrase('Limited time') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3" id="number_of_month" style="display: none">
|
|
||||||
<label class="form-label ol-form-label col-sm-3 col-form-label">{{ get_phrase('Number of month') }}</label>
|
|
||||||
|
|
||||||
<input class="form-control ol-form-control" type="number" name="number_of_month" min="1" placeholder="{{ get_phrase('After purchase, students can access the course until your selected month.') }}">
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7 mb-3 ">
|
|
||||||
<label for="enable_drip_content" class="form-label ol-form-label col-sm-4">{{ get_phrase('Enable drip content') }}
|
|
||||||
<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="0" name="enable_drip_content" class="form-check-input eRadioSuccess" id="drip_off" required checked>
|
|
||||||
<label for="drip_off" class="form-check-label">{{ get_phrase('Off') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="1" name="enable_drip_content" class="form-check-input eRadioPrimary" id="drip_on" required>
|
|
||||||
<label for="drip_on" class="form-check-label">{{ get_phrase('On') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="fpb-7">
|
|
||||||
<label for="thumbnail" class="form-label ol-form-label">{{ get_phrase('Thumbnail') }}</label>
|
|
||||||
<input type="file" name="thumbnail" class="form-control ol-form-control" id="thumbnail" accept="image/*" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="pt-2">
|
|
||||||
<button type="submit" class="btn ol-btn-primary float-end">{{ get_phrase('Submit') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@push('js')
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
//Start progress
|
|
||||||
var totalSteps = $('#v-pills-tab .nav-link').length
|
|
||||||
var progressVal = 100 / totalSteps;
|
|
||||||
$(function() {
|
|
||||||
var pValPerItem = progressVal;
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuemin', 0);
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuemax', pValPerItem);
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuenow', pValPerItem);
|
|
||||||
$('#courseFormProgress .progress-bar').width(pValPerItem + '%');
|
|
||||||
$('#courseFormProgress .progress-bar').text("Step 1 out of " + totalSteps);
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#v-pills-tab .nav-link").on('click', function() {
|
|
||||||
var currentStep = $("#v-pills-tab .nav-link").index(this) + 1;
|
|
||||||
var pValPerItem = currentStep * progressVal;
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuemin', 0);
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuemax', pValPerItem);
|
|
||||||
$('#courseFormProgress .progress-bar').attr('aria-valuenow', pValPerItem);
|
|
||||||
$('#courseFormProgress .progress-bar').width(pValPerItem + '%');
|
|
||||||
$('#courseFormProgress .progress-bar').text("Step " + currentStep + " out of " + totalSteps);
|
|
||||||
|
|
||||||
if (currentStep == totalSteps) {
|
|
||||||
$('#courseFormProgress .progress-bar').text("{{ get_phrase('Finish!') }}");
|
|
||||||
$('#courseFormProgress .progress-bar').addClass('bg-success');
|
|
||||||
} else {
|
|
||||||
$('#courseFormProgress .progress-bar').removeClass('bg-success');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//End progress
|
|
||||||
|
|
||||||
function checkExpiryPeriod(e) {
|
|
||||||
var expiryPeriod = $(e).val();
|
|
||||||
if (expiryPeriod == 'lifetime') {
|
|
||||||
$('#number_of_month').slideUp();
|
|
||||||
} else {
|
|
||||||
$('#number_of_month').slideDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@endpush
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
<input type="hidden" name="course_type" value="general" required>
|
|
||||||
<input type="hidden" name="instructors[]" value="{{ auth()->user()->id }}" required>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="title" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Course title') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="text" name="title" value="{{ $course_details->title }}" class="form-control ol-form-control" id="title" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="short_description" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Short description') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<textarea name="short_description" rows="3" class="form-control ol-form-control" id="short_description">{{ $course_details->short_description }}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="description" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Description') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<textarea name="description" rows="5" class="form-control ol-form-control text_editor" id="description">{!! removeScripts($course_details->description) !!}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Category') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="ol-select2" name="category_id" data-minimum-results-for-search="Infinity" required>
|
|
||||||
<option value="">{{ get_phrase('Select a category') }}</option>
|
|
||||||
@foreach (App\Models\Category::where('parent_id', 0)->orderBy('title', 'desc')->get() as $category)
|
|
||||||
<option value="{{ $category->id }}" @if ($course_details->category_id == $category->id) selected @endif>
|
|
||||||
{{ $category->title }}</option>
|
|
||||||
|
|
||||||
@foreach ($category->childs as $sub_category)
|
|
||||||
<option value="{{ $sub_category->id }}" @if ($course_details->category_id == $sub_category->id) selected @endif> --
|
|
||||||
{{ $sub_category->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Course level') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="ol-select2" name="level" required>
|
|
||||||
<option value="">{{ get_phrase('Select your course level') }}</option>
|
|
||||||
<option value="beginner" @if ($course_details->level == 'beginner') selected @endif>{{ get_phrase('Beginner') }}
|
|
||||||
</option>
|
|
||||||
<option value="intermediate" @if ($course_details->level == 'intermediate') selected @endif>
|
|
||||||
{{ get_phrase('Intermediate') }}</option>
|
|
||||||
<option value="advanced" @if ($course_details->level == 'advanced') selected @endif>{{ get_phrase('Advanced') }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Made in') }} <span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<select class="ol-select2" name="language" required>
|
|
||||||
<option value="">{{ get_phrase('Select your course language') }}</option>
|
|
||||||
@foreach (App\Models\Language::get() as $language)
|
|
||||||
<option value="{{ strtolower($language->name) }}" @if ($course_details->language == strtolower($language->name)) selected @endif class="text-capitalize">{{ $language->name }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="row mb-3 ">
|
|
||||||
<label for="course_status" class="col-sm-2 col-form-label">{{ get_phrase('Create as') }} <span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="active" name="status" class="form-check-input eRadioSuccess" id="status_active" @if ($course_details->status == 'active') checked @endif required disabled>
|
|
||||||
<label for="status_active" class="form-check-label">{{ get_phrase('Active') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="upcoming" name="status" class="form-check-input eRadioInfo" id="status_upcoming" @if ($course_details->status == 'upcoming') checked @endif required disabled>
|
|
||||||
<label for="status_upcoming" class="form-check-label">{{ get_phrase('Upcoming') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="deactive" name="status" class="form-check-input eRadioDark" id="status_deactive" @if ($course_details->status == 'deactive') checked @endif required disabled>
|
|
||||||
<label for="status_deactive" class="form-check-label">{{ get_phrase('Deactive') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="private" name="status" class="form-check-input eRadioPrimary" id="status_private" @if ($course_details->status == 'private') checked @endif required>
|
|
||||||
<label for="status_private" class="form-check-label">{{ get_phrase('Private') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="pending" name="status" class="form-check-input eRadioDanger" id="status_pending" @if ($course_details->status == 'pending') checked @endif required>
|
|
||||||
<label for="status_pending" class="form-check-label">{{ get_phrase('Pending') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" value="draft" name="status" class="form-check-input eRadioSecondary" id="status_draft" @if ($course_details->status == 'draft') checked @endif required>
|
|
||||||
<label for="status_draft" class="form-check-label">{{ get_phrase('Draft') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Pricing type') }}<span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" name="is_paid" value="1" class="form-check-input eRadioSuccess" id="paid" onchange="$('#paid-section').slideDown(200)" @if ($course_details->is_paid == 1) checked @endif>
|
|
||||||
<label for="paid" class="form-check-label">{{ get_phrase('Paid') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" name="is_paid" value="0" class="form-check-input eRadioSuccess" id="free" onchange="$('#paid-section').slideUp(200)" @if ($course_details->is_paid != 1) checked @endif>
|
|
||||||
<label for="free" class="form-check-label">{{ get_phrase('Free') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="paid-section @if ($course_details->is_paid != 1) d-hidden @endif" id="paid-section">
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="price" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Price') }} <small>({{ currency() }})</small><span class="text-danger ms-1">*</span></label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="number" name="price" value="{{ $course_details->price }}" class="form-control ol-form-control" id="price" min="1" step=".01" placeholder="{{ get_phrase('Enter your course price') }} ({{ currency() }})">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Discount type') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" name="discount_flag" value="1" class="form-check-input eRadioSuccess" id="discount_flag" @if ($course_details->discount_flag == 1) checked @endif>
|
|
||||||
<label for="discount_flag" class="form-check-label">{{ get_phrase('Check if this course has discount') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label for="discounted_price" class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Discounted price') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input type="number" name="discounted_price" value="{{ $course_details->discounted_price }}" class="form-control ol-form-control" id="discounted_price" min="1" step=".01" placeholder="{{ get_phrase('Enter your discount price') }} ({{ currency() }})">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Expiry period') }}</label>
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<div class="eRadios">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" id="lifetime_expiry_period" name="expiry_period" class="form-check-input eRadioSuccess" value="lifetime" onchange="$('#number_of_month').slideUp(200)" {{ $course_details->expiry_period ? '' : 'checked' }}>
|
|
||||||
<label class="form-check-label" for="lifetime_expiry_period">{{ get_phrase('Lifetime') }}</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="radio" id="limited_expiry_period" name="expiry_period" class="form-check-input eRadioSuccess" value="limited_time" onchange="$('#number_of_month').slideDown(200)" {{ $course_details->expiry_period ? 'checked' : '' }}>
|
|
||||||
<label class="form-check-label" for="limited_expiry_period">{{ get_phrase('Limited time') }}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="number-of-month @if (is_null($course_details->expiry_period)) d-hidden @endif" id="number_of_month">
|
|
||||||
|
|
||||||
<div class="row mb-3">
|
|
||||||
<label class="form-label ol-form-label col-sm-2 col-form-label">{{ get_phrase('Number of month') }}</label>
|
|
||||||
|
|
||||||
<div class="col-sm-10">
|
|
||||||
<input class="form-control ol-form-control" type="number" name="number_of_month" min="1" value="{{ $course_details->expiry_period }}" placeholder="{{ get_phrase('After purchase, students can access the course until your selected month.') }}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@ -1,356 +0,0 @@
|
|||||||
@extends('layouts.instructor')
|
|
||||||
@push('title', get_phrase('Course Manager'))
|
|
||||||
@section('content')
|
|
||||||
<div class="ol-card radius-8px">
|
|
||||||
<div class="ol-card-body my-3 py-12px px-20px">
|
|
||||||
<div class="d-flex align-items-center justify-content-between gap-3 flex-wrap flex-md-nowrap">
|
|
||||||
<h4 class="title fs-16px">
|
|
||||||
<i class="fi-rr-settings-sliders me-2"></i>
|
|
||||||
{{ get_phrase('Manage Courses') }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('instructor.course.create') }}"class="btn ol-btn-outline-secondary d-flex align-items-center cg-10px">
|
|
||||||
<span class="fi-rr-plus"></span>
|
|
||||||
<span>{{ get_phrase('Add New Course') }}</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row g-2 g-sm-3 mb-3 row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-4 row-cols-xl-5">
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('instructor.courses', ['status' => 'active']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $active_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Active courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('instructor.courses', ['status' => 'pending']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $pending_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Pending courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('instructor.courses', ['status' => 'upcoming']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $upcoming_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Upcoming courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('instructor.courses', ['price' => 'free']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $free_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Free courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<a href="{{ route('instructor.courses', ['price' => 'paid']) }}" class="d-block">
|
|
||||||
<div class="ol-card card-hover h-100">
|
|
||||||
<div class="ol-card-body px-3 py-12px">
|
|
||||||
<div class="d-flex align-items-center cg-12px">
|
|
||||||
<div>
|
|
||||||
<p class="sub-title fs-14px fw-semibold mb-2">{{ $paid_courses }}</p>
|
|
||||||
<h6 class="title fs-14px mb-1">{{ get_phrase('Paid courses') }}</h6>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Start Admin area -->
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="ol-card">
|
|
||||||
<div class="ol-card-body p-3 mb-5">
|
|
||||||
<div class="row mt-3 mb-4">
|
|
||||||
<div class="col-md-6 d-flex align-items-center gap-3">
|
|
||||||
<div class="custom-dropdown ms-2">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
{{ get_phrase('Export') }}
|
|
||||||
<i class="fi-rr-file-export ms-2"></i>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item export-btn" href="#" onclick="downloadPDF('.print-table', 'course-list')"><i class="fi-rr-file-pdf"></i> {{ get_phrase('PDF') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item export-btn" href="#" onclick="window.print();"><i class="fi-rr-print"></i> {{ get_phrase('Print') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="custom-dropdown dropdown-filter @if (!isset($_GET) || (isset($_GET) && count($_GET) == 0)) @endif">
|
|
||||||
<button class="dropdown-header btn ol-btn-light">
|
|
||||||
<i class="fi-rr-filter me-2"></i>
|
|
||||||
{{ get_phrase('Filter') }}
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET))
|
|
||||||
<span class="text-12px">
|
|
||||||
({{count($_GET)}})
|
|
||||||
</span>
|
|
||||||
@endif
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-list w-250px">
|
|
||||||
<li>
|
|
||||||
<form id="filter-dropdown" action="{{ route('instructor.courses') }}" method="get">
|
|
||||||
<div class="filter-option d-flex flex-column gap-3">
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Category') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="category" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}</option>
|
|
||||||
|
|
||||||
@foreach (App\Models\Category::where('parent_id', 0)->orderBy('title', 'desc')->get() as $category)
|
|
||||||
<option value="{{ $category->slug }}"@if (isset($parent_cat) && $parent_cat == $category->slug) selected @endif>
|
|
||||||
{{ $category->title }}</option>
|
|
||||||
|
|
||||||
@foreach ($category->childs as $sub_category)
|
|
||||||
<option value="{{ $sub_category->slug }}"@if (isset($child_cat) && $child_cat == $sub_category->slug) selected @endif>
|
|
||||||
--{{ $sub_category->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Status') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="status" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option value="active"@if (isset($status) && $status == 'active') selected @endif>{{ get_phrase('Active') }} </option>
|
|
||||||
<option value="inactive"@if (isset($status) && $status == 'inactive') selected @endif>{{ get_phrase('Inactive') }} </option>
|
|
||||||
<option value="pending"@if (isset($status) && $status == 'pending') selected @endif>{{ get_phrase('Pending') }} </option>
|
|
||||||
<option value="upcoming"@if (isset($status) && $status == 'upcoming') selected @endif>{{ get_phrase('Upcoming') }} </option>
|
|
||||||
<option value="private"@if (isset($status) && $status == 'private') selected @endif>{{ get_phrase('Private') }} </option>
|
|
||||||
<option value="draft"@if (isset($status) && $status == 'draft') selected @endif>{{ get_phrase('Draft') }} </option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Instructor') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="instructor" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
@foreach (App\Models\Course::select('user_id')->distinct()->get() as $course)
|
|
||||||
<option value="{{ $course->user_id }}"@if (isset($instructor) && $instructor == $course->user_id) selected @endif>
|
|
||||||
{{ ucfirst(get_user_info($course->user_id)->name) }}
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label for="eDataList" class="form-label ol-form-label">{{ get_phrase('Price') }}</label>
|
|
||||||
<select class="form-control ol-form-control ol-select2" data-toggle="select2" name="price" class="ol-select-2" data-placeholder="Type to search...">
|
|
||||||
<option value="all">{{ get_phrase('All') }}
|
|
||||||
</option>
|
|
||||||
|
|
||||||
<option value="free"@if (isset($price) && $price == 'free') selected @endif>
|
|
||||||
{{ get_phrase('Free') }}</option>
|
|
||||||
<option value="paid"@if (isset($price) && $price == 'paid') selected @endif>
|
|
||||||
{{ get_phrase('Paid') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="filter-button d-flex justify-content-end align-items-center mt-3">
|
|
||||||
<button type="submit" class="ol-btn-primary">{{ get_phrase('Apply') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if (isset($_GET) && count($_GET) > 0)
|
|
||||||
<a href="{{ route('instructor.courses') }}" class="me-2" data-bs-toggle="tooltip" title="{{ get_phrase('Clear') }}"><i class="fi-rr-cross-circle"></i></a>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 mt-3 mt-md-0">
|
|
||||||
<form action="{{ route('instructor.courses') }}" method="get">
|
|
||||||
<div class="row row-gap-3">
|
|
||||||
<div class="col-md-9 flex-grow-1">
|
|
||||||
<div class="search-input flex-grow-1">
|
|
||||||
<input type="text" name="search" value="{{ request('search') }}" placeholder="{{ get_phrase('Search Title') }}" class="ol-form-control form-control" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<button type="submit" class="btn ol-btn-primary w-100" id="submit-button">{{ get_phrase('Search') }}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
@if ($courses->count() > 0)
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($courses) . ' ' . get_phrase('of') . ' ' . $courses->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="table-responsive overflow-auto course_list overflow-auto" id="course_list">
|
|
||||||
<table class="table eTable eTable-2 print-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th scope="col">#</th>
|
|
||||||
<th scope="col">{{ get_phrase('Title') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Category') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Lesson & Section') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Enrolled Student') }}</th>
|
|
||||||
<th class="print-d-none" scope="col">{{ get_phrase('Status') }}</th>
|
|
||||||
<th scope="col">{{ get_phrase('Price') }}</th>
|
|
||||||
<th class="print-d-none" scope="col">{{ get_phrase('Options') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
@foreach ($courses as $key => $row)
|
|
||||||
@php
|
|
||||||
$query = App\Models\Watch_history::where('course_id', $row->id)
|
|
||||||
->where('student_id', auth()->user()->id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
$query1 = App\Models\Lesson::where('course_id', $row->id)
|
|
||||||
->orderBy('sort', 'asc')
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if (isset($query->watching_lesson_id) && $query->watching_lesson_id != '') {
|
|
||||||
$watching_lesson_id = $query->watching_lesson_id;
|
|
||||||
} elseif (isset($query1->id)) {
|
|
||||||
$watching_lesson_id = $query1->id;
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
<tr>
|
|
||||||
<th scope="row">
|
|
||||||
<p class="row-number">{{ ++$key }}</p>
|
|
||||||
</th>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_profile d-flex align-items-center min-w-200px">
|
|
||||||
<div class="dAdmin_profile_name">
|
|
||||||
<h4 class="title fs-14px">
|
|
||||||
<a href="{{ route('instructor.course.edit', [$row->id, 'tab' => 'curriculum']) }}">{{ ucfirst($row->title) }}</a>
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<a href="{{ route('instructor.courses', ['instructor' => $row->user_id]) }}">
|
|
||||||
<p class="sub-title2 text-12px">
|
|
||||||
{{ get_phrase('Instructor') }}:
|
|
||||||
{{ get_user_info($row->user_id)->name }}</p>
|
|
||||||
<p class="sub-title2 text-12px">{{ get_phrase('Email') }}:
|
|
||||||
{{ get_user_info($row->user_id)->email }}</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<a href="{{ route('instructor.courses', ['category' => $row->category->slug]) }}">{{ category_by_course($row->category_id)->title }}</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<a href="{{ route('instructor.course.edit', [$row->id, 'tab' => 'curriculum']) }}">
|
|
||||||
<p>{{ get_phrase('Lesson') }}: {{ lesson_count($row->id) }} </p>
|
|
||||||
<p> {{ get_phrase('Section') }}: {{ section_count($row->id) }} </p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="sub-title2 text-12px">
|
|
||||||
<p>
|
|
||||||
{{ course_enrollments($row->id). ' ' .get_phrase('students') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
<span class="badge bg-{{ $row->status }}">{{ get_phrase(ucfirst($row->status)) }}</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="dAdmin_info_name min-w-150px">
|
|
||||||
@if ($row->is_paid == 0)
|
|
||||||
<p class="eBadge ebg-soft-success">
|
|
||||||
{{ get_phrase('Free') }}
|
|
||||||
</p>
|
|
||||||
@else
|
|
||||||
<p>{{ currency($row->discounted_price) }}</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="print-d-none">
|
|
||||||
|
|
||||||
<div class="dropdown ol-icon-dropdown ol-icon-dropdown-transparent">
|
|
||||||
<button class="btn ol-btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
||||||
<span class="fi-rr-menu-dots-vertical"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" target="_blank" href="{{ route('course.details', $row->slug) }}">{{ get_phrase('View Course On Frontend') }}</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" target="_blank" href="{{ route('course.player', ['slug' => $row->slug]) }}">{{ get_phrase('Go To Course Playing Page') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" href="{{ route('instructor.course.edit', [$row->id, 'tab' => 'basic']) }}">{{ get_phrase('Edit Course') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('instructor.course.duplicate', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Duplicate Course') }}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="dropdown-item" onclick="confirmModal('{{ route('instructor.course.delete', $row->id) }}')" href="javascript:void(0)">{{ get_phrase('Delete Course') }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endforeach
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="admin-tInfo-pagi d-flex justify-content-between justify-content-center align-items-center flex-wrap gr-15">
|
|
||||||
<p class="admin-tInfo">
|
|
||||||
{{ get_phrase('Showing') . ' ' . count($courses) . ' ' . get_phrase('of') . ' ' . $courses->total() . ' ' . get_phrase('data') }}
|
|
||||||
</p>
|
|
||||||
{{ $courses->links() }}
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
@include('instructor.no_data')
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- End Admin area -->
|
|
||||||
@endsection
|
|
||||||
@ -1,134 +0,0 @@
|
|||||||
@php
|
|
||||||
$sections = App\Models\Section::where('course_id', $id)->orderBy('sort')->get();
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-primary ol-alert-primary ol-alert-sm mb-3" role="alert">
|
|
||||||
<p class="title2 fs-14px d-flex align-items-center">{{ get_phrase('Lesson type') }}:
|
|
||||||
@if ($lesson_type == 'html5')
|
|
||||||
{{ get_phrase('Video url') . ' [.mp4]' }}
|
|
||||||
@elseif ($lesson_type == 'video')
|
|
||||||
{{ get_phrase('Video file') }}
|
|
||||||
@elseif ($lesson_type == 'youtube' || $lesson_type == 'academy cloud' || $lesson_type == 'vimeo')
|
|
||||||
{{ ucfirst(get_phrase($lesson_type)) }} {{ get_phrase('Video') }}
|
|
||||||
@elseif($lesson_type == 'google_drive_video')
|
|
||||||
{{ get_phrase('Google drive video') }}
|
|
||||||
@elseif($lesson_type == 'document')
|
|
||||||
{{ get_phrase('Document file') }}
|
|
||||||
@elseif ($lesson_type == 'scorm')
|
|
||||||
{{ get_phrase('Scorm content') }}
|
|
||||||
@else
|
|
||||||
{{ ucfirst($lesson_type) }}
|
|
||||||
@endif
|
|
||||||
<a onclick="ajaxModal('{{ route('modal', ['instructor.course.lesson_type', 'id' => $id]) }}', '{{ get_phrase('Sort sections') }}')" class="btn text-primary ms-auto p-0" href="javascript:void(0)">{{ get_phrase('Change') }} <i class="fi-rr-arrow-alt-circle-right"></i></a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ACTUAL LESSON ADDING FORM -->
|
|
||||||
<form class="ajaxFormSubmission" action="{{ route('instructor.lesson.store') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<input type="hidden" name="course_id" value="{{ $id }}">
|
|
||||||
<input type="hidden" name="lesson_type" value="{{ $lesson_type }}">
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Section') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="section_id" required>
|
|
||||||
@foreach ($sections as $section)
|
|
||||||
<option value="{{ $section->id }}">{{ $section->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($lesson_type == 'youtube')
|
|
||||||
@include('instructor.course.youtube_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'academy_cloud')
|
|
||||||
@include('instructor.course.academy_cloud_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'vimeo')
|
|
||||||
@include('instructor.course.vimeo_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'html5')
|
|
||||||
@include('instructor.course.html5_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'video')
|
|
||||||
@include('instructor.course.video_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'amazon-s3')
|
|
||||||
@include('amazon_s3_type_lesson_add.php')
|
|
||||||
@elseif ($lesson_type == 'google_drive_video')
|
|
||||||
@include('instructor.course.google_drive_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'document')
|
|
||||||
@include('instructor.course.document_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'text')
|
|
||||||
@include('instructor.course.text_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'image')
|
|
||||||
@include('instructor.course.image_file_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'iframe')
|
|
||||||
@include('instructor.course.iframe_type_lesson_add')
|
|
||||||
@elseif ($lesson_type == 'scorm')
|
|
||||||
@include('instructor.course.scorm_type_lesson_add')
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Summary') }}</label>
|
|
||||||
<textarea name="summary" class="form-control text_editor"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group mb-3 d-none">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Do you want to keep it free as a preview lesson') }}
|
|
||||||
?</label>
|
|
||||||
<br>
|
|
||||||
<input type="checkbox" name="free_lesson" id="free_lesson" value="1" class="form-check-input">
|
|
||||||
<label for="free_lesson">{{ get_phrase('Mark as free lesson') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn ol-btn-primary ol-btn-sm w-100 formSubmissionBtn" type="submit" name="button">{{ get_phrase('Add lesson') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function ajax_get_video_details(url) {
|
|
||||||
$('#perloader').show();
|
|
||||||
if (checkURLValidity(url)) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('get.video.details') }}",
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
url: url
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log(response);
|
|
||||||
jQuery('#duration').val(response.duration);
|
|
||||||
$('#perloader').hide();
|
|
||||||
$('#invalid_url').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#invalid_url').show();
|
|
||||||
$('#perloader').hide();
|
|
||||||
jQuery('#duration').val('');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkURLValidity(video_url) {
|
|
||||||
var youtubePregMatch =
|
|
||||||
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
|
||||||
var vimeoPregMatch = /^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/;
|
|
||||||
if (video_url.match(youtubePregMatch)) {
|
|
||||||
return true;
|
|
||||||
} else if (vimeoPregMatch.test(video_url)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@include('instructor.init')
|
|
||||||
@ -1,133 +0,0 @@
|
|||||||
@php
|
|
||||||
$lessons = App\Models\Lesson::where('id', $id)->first();
|
|
||||||
$sections = App\Models\Section::where('course_id', $lessons->course_id)
|
|
||||||
->orderBy('sort')
|
|
||||||
->get();
|
|
||||||
$select_section = App\Models\Section::where('id', $lessons->section_id)->value('title');
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-info d-flex align-items-center py-2" role="alert">
|
|
||||||
{{ get_phrase('Lesson type') }}:
|
|
||||||
@if ($lessons->lesson_type == 'html5')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Video url') . ' [.mp4]' }}</strong>
|
|
||||||
@elseif ($lessons->lesson_type == 'system-video')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Video file') }}</strong>
|
|
||||||
@elseif ($lessons->lesson_type == 'scorm')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Scorm file') }}</strong>
|
|
||||||
@elseif ($lessons->video_type == 'youtube' || $lessons->video_type == 'vimeo')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase($lessons->video_type) }} {{ get_phrase('Video') }} </strong>
|
|
||||||
@elseif($lessons->lesson_type == 'google_drive_video')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Google drive video') }}</strong>
|
|
||||||
@elseif($lessons->lesson_type == 'document_type')
|
|
||||||
<strong class="text-capitalize ms-1">{{ get_phrase('Document file') }}</strong>
|
|
||||||
@else
|
|
||||||
<strong class="text-capitalize ms-1">{{ $lessons->lesson_type }}</strong>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- ACTUAL LESSON ADDING FORM -->
|
|
||||||
<form class="ajaxFormSubmission" action="{{ route('instructor.lesson.update') }}" method="post" enctype="multipart/form-data">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<input type="hidden" name="id" value="{{ $id }}">
|
|
||||||
<input type="hidden" name="lesson_type" value="{{ $lessons->lesson_type }}">
|
|
||||||
<div class="form-group eForm-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Title') }}</label>
|
|
||||||
<input type="text" name="title" class="form-control ol-form-control" value="{{ $lessons->title }}" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Section') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="section_id" required>
|
|
||||||
@foreach ($sections as $section)
|
|
||||||
<option value="{{ $section->id }}" @if ($lessons->section_id == $section->id) selected @endif>
|
|
||||||
{{ $section->title }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if ($lessons->lesson_type == 'video-url')
|
|
||||||
@include('instructor.course.youtube_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'vimeo-url')
|
|
||||||
@include('instructor.course.vimeo_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'system-video')
|
|
||||||
@include('instructor.course.video_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'scorm')
|
|
||||||
@include('instructor.course.scorm_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'html5')
|
|
||||||
@include('instructor.course.html5_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'google_drive')
|
|
||||||
@include('instructor.course.google_drive_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'document_type')
|
|
||||||
@include('instructor.course.document_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'text')
|
|
||||||
@include('instructor.course.text_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'image')
|
|
||||||
@include('instructor.course.image_file_type_lesson_edit')
|
|
||||||
@elseif ($lessons->lesson_type == 'iframe')
|
|
||||||
@include('instructor.course.iframe_type_lesson_edit')
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('summary') }}</label>
|
|
||||||
<textarea name="summary" class="form-control text_editor">{{ $lessons->summary }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2 d-none">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Do you want to keep it free as a preview lesson') }}
|
|
||||||
?</label>
|
|
||||||
<br>
|
|
||||||
<input type="checkbox" name="free_lesson" id="free_lesson" value="1">
|
|
||||||
<label for="free_lesson">{{ get_phrase('Mark as free lesson') }}</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<button class="btn ol-btn-primary ol-btn-sm w-100 formSubmissionBtn" type="submit" name="button">{{ get_phrase('Update lesson') }}</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function ajax_get_video_details(url) {
|
|
||||||
$('#perloader').show();
|
|
||||||
if (checkURLValidity(url)) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{{ route('get.video.details') }}",
|
|
||||||
type: 'POST',
|
|
||||||
data: {
|
|
||||||
url: url
|
|
||||||
},
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
|
||||||
},
|
|
||||||
success: function(response) {
|
|
||||||
console.log(response);
|
|
||||||
jQuery('#duration').val(response.duration);
|
|
||||||
$('#perloader').hide();
|
|
||||||
$('#invalid_url').hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$('#invalid_url').show();
|
|
||||||
$('#perloader').hide();
|
|
||||||
jQuery('#duration').val('');
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkURLValidity(video_url) {
|
|
||||||
var youtubePregMatch =
|
|
||||||
/^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
|
|
||||||
var vimeoPregMatch = /^(http\:\/\/|https\:\/\/)?(www\.)?(vimeo\.com\/)([0-9]+)$/;
|
|
||||||
if (video_url.match(youtubePregMatch)) {
|
|
||||||
return true;
|
|
||||||
} else if (vimeoPregMatch.test(video_url)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
@include('instructor.init')
|
|
||||||
@ -1,148 +0,0 @@
|
|||||||
@php
|
|
||||||
$course = App\Models\Course::where('id', $id)->first();
|
|
||||||
|
|
||||||
$selected_lesson = 'youtube';
|
|
||||||
if (isset($param3) && !empty($param3)) {
|
|
||||||
$selected_lesson = $param3;
|
|
||||||
}
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="alert alert-primary ol-alert-primary ol-alert-sm mb-3" role="alert">
|
|
||||||
<p class="title2 fs-14px">{{ get_phrase('Course') }}:
|
|
||||||
<span class="title">{{ $course->title }}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form action="">
|
|
||||||
<input id="course_id_for_lesson" type="hidden" value="" name="course_id_for_lesson">
|
|
||||||
<div class="ol-modal-form">
|
|
||||||
<h6 class="title fs-16px mb-3">{{ get_phrase('Select lesson type') }}</h6>
|
|
||||||
<div class="row row-12px row-cols-1 row-cols-sm-2 mb-20px">
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-youtube">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-square-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('YouTube Video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-youtube" value="youtube" @if ($selected_lesson == 'youtube') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-vimeo">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-circle-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Vimeo Video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-vimeo" value="vimeo" @if ($selected_lesson == 'vimeo') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-videofile">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/video-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Video file') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-videofile" value="video" @if ($selected_lesson == 'video') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-url">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/link-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Video url [ .mp4 ]') }}</p>
|
|
||||||
</div>
|
|
||||||
<input value="html5" class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-url">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-drive">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/document-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Google drive video') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-drive" value="google_drive_video" @if ($selected_lesson == 'google_drive_video') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-document">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/document-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Document file') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-document" value="document" @if ($selected_lesson == 'document') checked @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-text">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/text-block-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Text') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-text" value="text" @if ($selected_lesson == 'text') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-image">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Image') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-image" value="image" @if ($selected_lesson == 'image') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap" for="radio-iframe">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Iframe embed') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type" id="radio-iframe" value="iframe" @if ($selected_lesson == 'iframe') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col">
|
|
||||||
<label class="ol-radiobox-1 d-flex align-items-center justify-content-between flex-wrap"
|
|
||||||
for="radio-scorm">
|
|
||||||
<div class="title-icon d-flex align-items-center">
|
|
||||||
<img src="assets/images/icons/volume-black-18.svg" alt="">
|
|
||||||
<p class="title">{{ get_phrase('Scorm Content') }}</p>
|
|
||||||
</div>
|
|
||||||
<input class="form-check-input form-check-input-radio" type="radio" name="lesson_type"
|
|
||||||
id="radio-scorm" value="scorm"
|
|
||||||
@if ($selected_lesson == 'scorm') {{ get_phrase('checked') }} @endif>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="mt-3">
|
|
||||||
<a href="javascript:void(0)" type="button" class="btn btn-primary" data-toggle="modal" data-dismiss="modal" id="lesson-add-modal" onclick="showLessonAddModal()">{{ get_phrase('Next') }}
|
|
||||||
<i class="fi-rr-angle-small-right"></i> </a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function showLessonAddModal() {
|
|
||||||
var url = $("input[name=lesson_type]:checked").val();
|
|
||||||
ajaxModal('{{ route('modal', ['instructor.course.lesson_add', 'id' => $course->id]) }}&lesson_type=' + url,
|
|
||||||
'{{ get_phrase('Add new lesson') }}')
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
<input type="hidden" name="lesson_type" value="scorm">
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Select scorm provider') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="scorm_provider" required>
|
|
||||||
<option value="">{{ get_phrase('Select a provider') }}</option>
|
|
||||||
<option value="iSpring">{{ get_phrase('iSpring') }}</option>
|
|
||||||
<option value="articulate">{{ get_phrase('Articulate') }}</option>
|
|
||||||
<option value="adobeCaptivate">{{ get_phrase('Adobe Captivate') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Upload scorm file') }}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="custom-file w-100">
|
|
||||||
<input type="file" class="form-control ol-form-control" id="scorm_file" name="scorm_file" accept=".zip"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
initializeDurationPickers([".duration-picker"]);
|
|
||||||
</script>
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<input type="hidden" name="lesson_type" value="scorm">
|
|
||||||
<input type="hidden" name="attachment" value="{{ $lessons->attachment }}">
|
|
||||||
|
|
||||||
<div class="form-group mb-3">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Select scorm provider') }}</label>
|
|
||||||
<select class="form-control ol-select2" data-toggle="select2" name="scorm_provider" required>
|
|
||||||
<option value="">{{ get_phrase('Select a provider') }}</option>
|
|
||||||
<option value="iSpring" @if ($lessons->attachment_type == 'iSpring') selected @endif>{{ get_phrase('iSpring') }}</option>
|
|
||||||
<option value="articulate" @if ($lessons->attachment_type == 'articulate') selected @endif>{{ get_phrase('Articulate') }}
|
|
||||||
</option>
|
|
||||||
<option value="adobeCaptivate" @if ($lessons->attachment_type == 'adobeCaptivate') selected @endif>
|
|
||||||
{{ get_phrase('Adobe Captivate') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label class="form-label ol-form-label">{{ get_phrase('Update scorm file') }}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<div class="custom-file w-100">
|
|
||||||
<input type="file" class="form-control ol-form-control" id="scorm_file" name="scorm_file" accept=".zip"
|
|
||||||
required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
"use strict";
|
|
||||||
initializeDurationPickers([".duration-picker"]);
|
|
||||||
</script>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user