forked from miguel456/rbrecruiter
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
bca6020ab0 | |||
1f50faaea7 | |||
e978a5417b | |||
4dc412e53c | |||
bd0664ce0d | |||
4b390ea536 | |||
035c9399a6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
|||||||
/public/storage
|
/public/storage
|
||||||
/storage/*.key
|
/storage/*.key
|
||||||
/vendor
|
/vendor
|
||||||
|
/tools
|
||||||
.env
|
.env
|
||||||
.env.backup
|
.env.backup
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
|
5
.phive/phars.xml
Normal file
5
.phive/phars.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phive xmlns="https://phar.io/phive">
|
||||||
|
<phar name="phpunit" version="^9.2.5" installed="9.2.5" location="./tools/phpunit" copy="false"/>
|
||||||
|
<phar name="php-cs-fixer" version="^2.16.4" installed="2.16.4" location="./tools/php-cs-fixer" copy="false"/>
|
||||||
|
</phive>
|
@@ -119,13 +119,14 @@ class Install extends Command
|
|||||||
$this->info('>> Saved configuration settings!');
|
$this->info('>> Saved configuration settings!');
|
||||||
$this->info('>> Preparing database...');
|
$this->info('>> Preparing database...');
|
||||||
|
|
||||||
|
$this->callSilent('config:cache');
|
||||||
$this->call('migrate');
|
$this->call('migrate');
|
||||||
$this->call('db:seed');
|
$this->call('db:seed');
|
||||||
|
|
||||||
touch($basePath . '/INSTALLED');
|
touch($basePath . '/INSTALLED');
|
||||||
|
|
||||||
$this->call('up');
|
$this->call('up');
|
||||||
$this->info('>> All done! Visit ' . $baseURL . ' to start using your brand new installation of Raspberry Teams!');
|
$this->info('>> All done! Visit ' . $basePath . ' to start using your brand new installation of Raspberry Teams!');
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
14
app/Facades/ContextAwareValidation.php
Normal file
14
app/Facades/ContextAwareValidation.php
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Facades;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
|
||||||
|
class ContextAwareValidation extends Facade
|
||||||
|
{
|
||||||
|
|
||||||
|
protected static function getFacadeAccessor()
|
||||||
|
{
|
||||||
|
return 'contextAwareValidator';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -16,7 +16,7 @@ class Form extends Model
|
|||||||
|
|
||||||
public function vacancies()
|
public function vacancies()
|
||||||
{
|
{
|
||||||
return $this->hasMany('vacancies', 'vacancyFormID', 'id');
|
return $this->hasMany('App\Vacancy', 'vacancyFormID', 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function responses()
|
public function responses()
|
||||||
|
72
app/Helpers/ContextAwareValidator.php
Normal file
72
app/Helpers/ContextAwareValidator.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
class ContextAwareValidator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The getValidator() method will take an array of fields from the request body, iterates through them,
|
||||||
|
* and dynamically adds validation rules for them. Depending on parameters, it may or may not generate
|
||||||
|
* a form structure for rendering purposes.
|
||||||
|
*
|
||||||
|
* This method is mostly meant by internal use by means of static proxies (Facades), in order to reduce code repetition;
|
||||||
|
* Using it outside it's directed scope may cause unexpected results; For instance, the method expects inputs to be in array format, e.g. myFieldNameID1[],
|
||||||
|
* myFieldNameID2[], and so on and so forth.
|
||||||
|
*
|
||||||
|
* This isn't checked by the code yet, but if you're implementing it this way in the HTML markup, make sure it's consistent (e.g. use a loop).
|
||||||
|
*
|
||||||
|
* P.S This method automatically ignores the CSRF token for validation.
|
||||||
|
*
|
||||||
|
* @param array $fields The request form fields
|
||||||
|
* @param bool $generateStructure Whether to incldue a JSON-ready form structure for rendering
|
||||||
|
* @param bool $includeFormName Whether to include formName in the list of validation rules
|
||||||
|
* @return Validator|Collection A validator instance you can use to check for validity, or a Collection with a validator and structure (validator, structure)
|
||||||
|
*/
|
||||||
|
public function getValidator(array $fields, bool $generateStructure = false, bool $includeFormName = false)
|
||||||
|
{
|
||||||
|
$formStructure = [];
|
||||||
|
$validator = [];
|
||||||
|
|
||||||
|
$excludedNames = [
|
||||||
|
'_token',
|
||||||
|
'_method',
|
||||||
|
'formName'
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($includeFormName)
|
||||||
|
{
|
||||||
|
$validator['formName'] = 'required|string|max:100';
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($fields as $fieldName => $field)
|
||||||
|
{
|
||||||
|
if(!in_array($fieldName, $excludedNames))
|
||||||
|
{
|
||||||
|
$validator[$fieldName . ".0"] = 'required|string';
|
||||||
|
$validator[$fieldName . ".1"] = 'required|string';
|
||||||
|
|
||||||
|
if ($generateStructure)
|
||||||
|
{
|
||||||
|
$formStructure['fields'][$fieldName]['title'] = $field[0];
|
||||||
|
$formStructure['fields'][$fieldName]['type'] = $field[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$validatorInstance = Validator::make($fields, $validator);
|
||||||
|
|
||||||
|
return ($generateStructure) ?
|
||||||
|
collect([
|
||||||
|
'validator' => $validatorInstance,
|
||||||
|
'structure' => json_encode($formStructure)
|
||||||
|
])
|
||||||
|
: $validatorInstance;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -45,10 +45,9 @@ class ApplicationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function showUserApp(Request $request, $applicationID)
|
public function showUserApp(Request $request, $applicationID)
|
||||||
{
|
{
|
||||||
|
// TODO: Inject it instead (do this where there is no injection, not just here)
|
||||||
$application = Application::find($applicationID);
|
$application = Application::find($applicationID);
|
||||||
|
|
||||||
$this->authorize('view', $application);
|
$this->authorize('view', $application);
|
||||||
@@ -77,6 +76,12 @@ class ApplicationController extends Controller
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function showAllApps()
|
||||||
|
{
|
||||||
|
return view('dashboard.appmanagement.all')
|
||||||
|
->with('applications', Application::paginate(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function showAllPendingApps()
|
public function showAllPendingApps()
|
||||||
{
|
{
|
||||||
@@ -87,9 +92,6 @@ class ApplicationController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function showPendingInterview()
|
public function showPendingInterview()
|
||||||
{
|
{
|
||||||
$this->authorize('viewAny', Application::class);
|
$this->authorize('viewAny', Application::class);
|
||||||
@@ -280,4 +282,16 @@ class ApplicationController extends Controller
|
|||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(Request $request, Application $application)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->authorize('delete', $application);
|
||||||
|
$application->delete(); // observers will run, cleaning it up
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Application deleted. Comments, appointments and responses have also been deleted.');
|
||||||
|
return redirect()->back();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,8 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
use ContextAwareValidator;
|
||||||
|
|
||||||
class FormController extends Controller
|
class FormController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -29,39 +31,17 @@ class FormController extends Controller
|
|||||||
{
|
{
|
||||||
|
|
||||||
$this->authorize('create', Form::class);
|
$this->authorize('create', Form::class);
|
||||||
|
$fields = $request->all();
|
||||||
|
|
||||||
$formFields = $request->all();
|
$contextValidation = ContextAwareValidator::getValidator($fields, true, true);
|
||||||
|
|
||||||
$formStructure = [];
|
if (!$contextValidation->get('validator')->fails())
|
||||||
$excludedNames = [
|
|
||||||
'_token',
|
|
||||||
'formName' // It's added outside the loop. Not excluding causes unwanted duplication.
|
|
||||||
];
|
|
||||||
$validator = [
|
|
||||||
'formName' => 'required|string|max:100'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($formFields as $fieldName => $field)
|
|
||||||
{
|
{
|
||||||
if(!in_array($fieldName, $excludedNames))
|
$storableFormStructure = $contextValidation->get('structure');
|
||||||
{
|
|
||||||
$validator[$fieldName . ".0"] = 'required|string';
|
|
||||||
$validator[$fieldName . ".1"] = 'required|string';
|
|
||||||
|
|
||||||
$formStructure['fields'][$fieldName]['title'] = $field[0];
|
|
||||||
$formStructure['fields'][$fieldName]['type'] = $field[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$validation = Validator::make($formFields, $validator);
|
|
||||||
|
|
||||||
if (!$validation->fails())
|
|
||||||
{
|
|
||||||
$storableFormStructure = json_encode($formStructure);
|
|
||||||
|
|
||||||
Form::create(
|
Form::create(
|
||||||
[
|
[
|
||||||
'formName' => $formFields['formName'],
|
'formName' => $fields['formName'],
|
||||||
'formStructure' => $storableFormStructure,
|
'formStructure' => $storableFormStructure,
|
||||||
'formStatus' => 'ACTIVE'
|
'formStatus' => 'ACTIVE'
|
||||||
]
|
]
|
||||||
@@ -71,7 +51,7 @@ class FormController extends Controller
|
|||||||
return redirect()->to(route('showForms'));
|
return redirect()->to(route('showForms'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->flash('errors', $validation->errors()->getMessages());
|
$request->session()->flash('errors', $contextValidation->get('validator')->errors()->getMessages());
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,19 +60,68 @@ class FormController extends Controller
|
|||||||
|
|
||||||
$form = Form::find($id);
|
$form = Form::find($id);
|
||||||
$this->authorize('delete', $form);
|
$this->authorize('delete', $form);
|
||||||
|
$deletable = true;
|
||||||
|
|
||||||
// TODO: Check if form is linked to vacancies before allowing deletion
|
|
||||||
if (!is_null($form))
|
if (!is_null($form) && !is_null($form->vacancies) && $form->vacancies->count() !== 0 || !is_null($form->responses))
|
||||||
{
|
{
|
||||||
$form->delete();
|
$deletable = false;
|
||||||
|
}
|
||||||
$request->session()->flash('success', 'Form deleted successfully.');
|
|
||||||
return redirect()->back();
|
if ($deletable)
|
||||||
|
{
|
||||||
|
$form->delete();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Form deleted successfully.');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$request->session()->flash('error', 'You cannot delete this form because it\'s tied to one or more applications and ranks, or because it doesn\'t exist.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->flash('error', 'The form you\'re trying to delete does not exist.');
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function preview(Request $request, Form $form)
|
||||||
|
{
|
||||||
|
return view('dashboard.administration.formpreview')
|
||||||
|
->with('form', json_decode($form->formStructure, true))
|
||||||
|
->with('title', $form->formName)
|
||||||
|
->with('formID', $form->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit(Request $request, Form $form)
|
||||||
|
{
|
||||||
|
return view('dashboard.administration.editform')
|
||||||
|
->with('formStructure', json_decode($form->formStructure, true))
|
||||||
|
->with('title', $form->formName)
|
||||||
|
->with('formID', $form->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, Form $form)
|
||||||
|
{
|
||||||
|
$contextValidation = ContextAwareValidator::getValidator($request->all(), true);
|
||||||
|
$this->authorize('update', $form);
|
||||||
|
|
||||||
|
|
||||||
|
if (!$contextValidation->get('validator')->fails())
|
||||||
|
{
|
||||||
|
// Add the new structure into the form. New, subsquent fields will be identified by the "new" prefix
|
||||||
|
// This prefix doesn't actually change the app's behavior when it receives applications.
|
||||||
|
// Additionally, old applications won't of course display new and updated fields, because we can't travel into the past and get data for them
|
||||||
|
$form->formStructure = $contextValidation->get('structure');
|
||||||
|
$form->save();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Hooray! Your form was updated. New applications for it\'s vacancy will use it.');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$request->session()->flash('errors', $contextValidation->get('validator')->errors()->getMessages());
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->to(route('previewForm', ['form' => $form->id]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,14 +15,11 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// TODO: Relationships for Applications, Users and Responses
|
|
||||||
// Also prevent apps if user already has one in the space of 30d
|
|
||||||
// Display apps in the relevant menus
|
|
||||||
|
|
||||||
$positions = DB::table('vacancies')
|
$positions = Vacancy::where('vacancyStatus', 'OPEN')
|
||||||
->where('vacancyStatus', 'OPEN')
|
->where('vacancyCount', '<>', 0)
|
||||||
->where('vacancyCount', '!=', 0)
|
->get();
|
||||||
->get();
|
|
||||||
|
|
||||||
return view('home')
|
return view('home')
|
||||||
->with('positions', $positions);
|
->with('positions', $positions);
|
||||||
|
@@ -3,15 +3,19 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Http\Requests\VacancyRequest;
|
use App\Http\Requests\VacancyRequest;
|
||||||
|
use App\Http\Requests\VacancyEditRequest;
|
||||||
|
|
||||||
use App\Vacancy;
|
use App\Vacancy;
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Form;
|
use App\Form;
|
||||||
|
|
||||||
use App\Notifications\VacancyClosed;
|
use App\Notifications\VacancyClosed;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
|
||||||
class VacancyController extends Controller
|
class VacancyController extends Controller
|
||||||
{
|
{
|
||||||
public function index()
|
public function index()
|
||||||
@@ -31,10 +35,16 @@ class VacancyController extends Controller
|
|||||||
|
|
||||||
if (!is_null($form))
|
if (!is_null($form))
|
||||||
{
|
{
|
||||||
|
/* note: since we can't convert HTML back to Markdown, we'll have to do the converting when the user requests a page,
|
||||||
|
* and leave the database with Markdown only so it can be used and edited everywhere.
|
||||||
|
* for several vacancies, this would require looping through all of them and replacing MD with HTML, which is obviously not the most clean solution;
|
||||||
|
* however, the Model can be configured to return MD instead of HTML on that specific field saving us from looping.
|
||||||
|
*/
|
||||||
Vacancy::create([
|
Vacancy::create([
|
||||||
|
|
||||||
'vacancyName' => $request->vacancyName,
|
'vacancyName' => $request->vacancyName,
|
||||||
'vacancyDescription' => $request->vacancyDescription,
|
'vacancyDescription' => $request->vacancyDescription,
|
||||||
|
'vacancyFullDescription' => $request->vacancyFullDescription,
|
||||||
'vacancySlug' => Str::slug($request->vacancyName),
|
'vacancySlug' => Str::slug($request->vacancyName),
|
||||||
'permissionGroupName' => $request->permissionGroup,
|
'permissionGroupName' => $request->permissionGroup,
|
||||||
'discordRoleID' => $request->discordRole,
|
'discordRoleID' => $request->discordRole,
|
||||||
@@ -101,4 +111,29 @@ class VacancyController extends Controller
|
|||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function edit(Request $request, Vacancy $position)
|
||||||
|
{
|
||||||
|
$this->authorize('update', $vacancy);
|
||||||
|
return view('dashboard.administration.editposition')
|
||||||
|
->with('vacancy', $position);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function update(VacancyEditRequest $request, Vacancy $position)
|
||||||
|
{
|
||||||
|
$this->authorize('update', $vacancy);
|
||||||
|
|
||||||
|
$position->vacancyFullDescription = $request->vacancyFullDescription;
|
||||||
|
$position->vacancyDescription = $request->vacancyDescription;
|
||||||
|
$position->vacancyCount = $request->vacancyCount;
|
||||||
|
|
||||||
|
$position->save();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Vacancy successfully updated.');
|
||||||
|
return redirect()->back();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
34
app/Http/Requests/VacancyEditRequest.php
Normal file
34
app/Http/Requests/VacancyEditRequest.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
|
||||||
|
class VacancyEditRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return Auth::user()->can('admin.hiring.vacancy.edit');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'vacancyDescription' => 'required|string',
|
||||||
|
'vacancyFullDescription' => 'nullable|string',
|
||||||
|
'vacancyCount' => 'required|integer|min:1'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@@ -26,6 +26,7 @@ class VacancyRequest extends FormRequest
|
|||||||
return [
|
return [
|
||||||
'vacancyName' => 'required|string',
|
'vacancyName' => 'required|string',
|
||||||
'vacancyDescription' => 'required|string',
|
'vacancyDescription' => 'required|string',
|
||||||
|
'vacancyFullDescription' => 'nullable|string',
|
||||||
'permissionGroup' => 'required|string',
|
'permissionGroup' => 'required|string',
|
||||||
'discordRole' => 'required|string',
|
'discordRole' => 'required|string',
|
||||||
'vacancyCount' => 'required|integer',
|
'vacancyCount' => 'required|integer',
|
||||||
|
@@ -6,12 +6,13 @@ use Illuminate\Bus\Queueable;
|
|||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Notifications\Messages\MailMessage;
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
use Illuminate\Notifications\Notification;
|
use Illuminate\Notifications\Notification;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
use App\Vacancy;
|
use App\Vacancy;
|
||||||
|
|
||||||
class VacancyClosed extends Notification implements ShouldQueue
|
class VacancyClosed extends Notification implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Queueable;
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
protected $vacancy;
|
protected $vacancy;
|
||||||
|
|
||||||
|
93
app/Observers/ApplicationObserver.php
Normal file
93
app/Observers/ApplicationObserver.php
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Application;
|
||||||
|
|
||||||
|
class ApplicationObserver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the application "created" event.
|
||||||
|
*
|
||||||
|
* @param \App\Application $application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function created(Application $application)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the application "updated" event.
|
||||||
|
*
|
||||||
|
* @param \App\Application $application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updated(Application $application)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleting(Application $application)
|
||||||
|
{
|
||||||
|
$application->response()->delete();
|
||||||
|
$votes = $application->votes;
|
||||||
|
|
||||||
|
foreach ($votes as $vote)
|
||||||
|
{
|
||||||
|
Log::debug('Referential integrity cleanup: Deleting and detaching vote ' . $vote->id);
|
||||||
|
$vote->application()->detach($application->id);
|
||||||
|
$vote->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($application->appointment))
|
||||||
|
{
|
||||||
|
Log::debug('RIC: Deleting appointment!');
|
||||||
|
$application->appointment()->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$application->comments->isEmpty())
|
||||||
|
{
|
||||||
|
Log::debug('RIC: Deleting comments!');
|
||||||
|
foreach($application->comments as $comment)
|
||||||
|
{
|
||||||
|
$comment->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// application can now be deleted
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the application "deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Application $application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleted(Application $application)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the application "restored" event.
|
||||||
|
*
|
||||||
|
* @param \App\Application $application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restored(Application $application)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the application "force deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Application $application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceDeleted(Application $application)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@@ -48,30 +48,7 @@ class UserObserver
|
|||||||
Log::debug('RIC: Now trying to delete applications and responses...');
|
Log::debug('RIC: Now trying to delete applications and responses...');
|
||||||
foreach($applications as $application)
|
foreach($applications as $application)
|
||||||
{
|
{
|
||||||
$application->response()->delete();
|
// code moved to Application observer, where it gets rid of attached elements individually
|
||||||
$votes = $application->votes;
|
|
||||||
|
|
||||||
foreach ($votes as $vote)
|
|
||||||
{
|
|
||||||
Log::debug('RIC: Deleting and detaching vote ' . $vote->id);
|
|
||||||
$vote->application()->detach($application->id);
|
|
||||||
$vote->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_null($application->appointment))
|
|
||||||
{
|
|
||||||
Log::debug('RIC: Deleting appointment!');
|
|
||||||
$application->appointment()->delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$application->comments->isEmpty())
|
|
||||||
{
|
|
||||||
Log::debug('RIC: Deleting comments!');
|
|
||||||
foreach($application->comments as $comment)
|
|
||||||
{
|
|
||||||
$comment->delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log::debug('RIC: Deleting application ' . $application->id);
|
Log::debug('RIC: Deleting application ' . $application->id);
|
||||||
$application->delete();
|
$application->delete();
|
||||||
|
|
||||||
|
64
app/Observers/VacancyObserver.php
Normal file
64
app/Observers/VacancyObserver.php
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Observers;
|
||||||
|
|
||||||
|
use App\Vacancy;
|
||||||
|
|
||||||
|
|
||||||
|
class VacancyObserver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the vacancy "created" event.
|
||||||
|
*
|
||||||
|
* @param \App\Vacancy $vacancy
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function created(Vacancy $vacancy)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the vacancy "updated" event.
|
||||||
|
*
|
||||||
|
* @param \App\Vacancy $vacancy
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updated(Vacancy $vacancy)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the vacancy "deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Vacancy $vacancy
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleted(Vacancy $vacancy)
|
||||||
|
{
|
||||||
|
// TODO: Handle deletion of children's data
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the vacancy "restored" event.
|
||||||
|
*
|
||||||
|
* @param \App\Vacancy $vacancy
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function restored(Vacancy $vacancy)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the vacancy "force deleted" event.
|
||||||
|
*
|
||||||
|
* @param \App\Vacancy $vacancy
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceDeleted(Vacancy $vacancy)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@@ -45,4 +45,11 @@ class ApplicationPolicy
|
|||||||
{
|
{
|
||||||
return $user->hasAnyRole('admin', 'hiringManager');
|
return $user->hasAnyRole('admin', 'hiringManager');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function delete(User $user, Application $application)
|
||||||
|
{
|
||||||
|
|
||||||
|
return $user->hasRole('admin');
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,7 @@ class FormPolicy
|
|||||||
*/
|
*/
|
||||||
public function update(User $user, Form $form)
|
public function update(User $user, Form $form)
|
||||||
{
|
{
|
||||||
// unused
|
return $user->can('admin.hiring.forms');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -53,7 +53,7 @@ class VacancyPolicy
|
|||||||
*/
|
*/
|
||||||
public function update(User $user, Vacancy $vacancy)
|
public function update(User $user, Vacancy $vacancy)
|
||||||
{
|
{
|
||||||
return $user->hasRole('admin', 'hiringManager');
|
return $user->hasAnyRole('admin', 'hiringManager');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
34
app/Providers/ContextAwareValidatorProvider.php
Normal file
34
app/Providers/ContextAwareValidatorProvider.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
use App;
|
||||||
|
|
||||||
|
class ContextAwareValidatorProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
App::bind('contextAwareValidator', function(){
|
||||||
|
|
||||||
|
return new App\Helpers\ContextAwareValidator();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@@ -6,6 +6,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
use GrahamCampbell\Markdown\Facades\Markdown;
|
||||||
|
|
||||||
|
|
||||||
class Vacancy extends Model
|
class Vacancy extends Model
|
||||||
{
|
{
|
||||||
public $fillable = [
|
public $fillable = [
|
||||||
@@ -13,6 +16,7 @@ class Vacancy extends Model
|
|||||||
'permissionGroupName',
|
'permissionGroupName',
|
||||||
'vacancyName',
|
'vacancyName',
|
||||||
'vacancyDescription',
|
'vacancyDescription',
|
||||||
|
'vacancyFullDescription',
|
||||||
'discordRoleID',
|
'discordRoleID',
|
||||||
'vacancyFormID',
|
'vacancyFormID',
|
||||||
'vacancyCount',
|
'vacancyCount',
|
||||||
@@ -21,6 +25,26 @@ class Vacancy extends Model
|
|||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the HTML variant of the vacancyFullDescription attribute.
|
||||||
|
*
|
||||||
|
* @param string $value The original value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getVacancyFullDescriptionAttribute($value)
|
||||||
|
{
|
||||||
|
if (!is_null($value))
|
||||||
|
{
|
||||||
|
return Markdown::convertToHTML($value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function forms()
|
public function forms()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\Form', 'vacancyFormID', 'id');
|
return $this->belongsTo('App\Form', 'vacancyFormID', 'id');
|
||||||
|
33
app/View/Components/Form.php
Normal file
33
app/View/Components/Form.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components;
|
||||||
|
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class Form extends Component
|
||||||
|
{
|
||||||
|
|
||||||
|
public $formFields;
|
||||||
|
|
||||||
|
|
||||||
|
public $disableFields = false;
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($disableFields = false)
|
||||||
|
{
|
||||||
|
$this->disableFields = $disableFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View|string
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('components.form');
|
||||||
|
}
|
||||||
|
}
|
33
app/View/Components/NoPermission.php
Normal file
33
app/View/Components/NoPermission.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\View\Components;
|
||||||
|
|
||||||
|
use Illuminate\View\Component;
|
||||||
|
|
||||||
|
class NoPermission extends Component
|
||||||
|
{
|
||||||
|
public $type;
|
||||||
|
|
||||||
|
public $inDashboard;
|
||||||
|
/**
|
||||||
|
* Create a new component instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($type, $inDashboard = true)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
|
||||||
|
$this->inDashboard = $inDashboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the view / contents that represent the component.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\View\View|string
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('components.no-permission');
|
||||||
|
}
|
||||||
|
}
|
@@ -15,6 +15,7 @@
|
|||||||
"fideloper/proxy": "^4.2",
|
"fideloper/proxy": "^4.2",
|
||||||
"fruitcake/laravel-cors": "^1.0",
|
"fruitcake/laravel-cors": "^1.0",
|
||||||
"geo-sot/laravel-env-editor": "^0.9.9",
|
"geo-sot/laravel-env-editor": "^0.9.9",
|
||||||
|
"graham-campbell/markdown": "^12.0",
|
||||||
"guzzlehttp/guzzle": "^6.5",
|
"guzzlehttp/guzzle": "^6.5",
|
||||||
"jeroennoten/laravel-adminlte": "^3.2",
|
"jeroennoten/laravel-adminlte": "^3.2",
|
||||||
"laravel/framework": "^7.0",
|
"laravel/framework": "^7.0",
|
||||||
|
69
composer.lock
generated
69
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "16e8efbacd91ef3417b21bd2648e1629",
|
"content-hash": "51429857899e8134bbe6b4fa61145cc3",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "almasaeed2010/adminlte",
|
"name": "almasaeed2010/adminlte",
|
||||||
@@ -1091,6 +1091,73 @@
|
|||||||
],
|
],
|
||||||
"time": "2020-04-17T23:33:36+00:00"
|
"time": "2020-04-17T23:33:36+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "graham-campbell/markdown",
|
||||||
|
"version": "v12.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/GrahamCampbell/Laravel-Markdown.git",
|
||||||
|
"reference": "584eb9f24004238b80ee98b6e7be82f0933554dd"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/GrahamCampbell/Laravel-Markdown/zipball/584eb9f24004238b80ee98b6e7be82f0933554dd",
|
||||||
|
"reference": "584eb9f24004238b80ee98b6e7be82f0933554dd",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"illuminate/contracts": "^6.0|^7.0",
|
||||||
|
"illuminate/support": "^6.0|^7.0",
|
||||||
|
"illuminate/view": "^6.0|^7.0",
|
||||||
|
"league/commonmark": "^1.3",
|
||||||
|
"php": "^7.2.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"graham-campbell/analyzer": "^3.0",
|
||||||
|
"graham-campbell/testbench": "^5.4",
|
||||||
|
"mockery/mockery": "^1.3.1",
|
||||||
|
"phpunit/phpunit": "^8.5|^9.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "12.0-dev"
|
||||||
|
},
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"GrahamCampbell\\Markdown\\MarkdownServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"GrahamCampbell\\Markdown\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Graham Campbell",
|
||||||
|
"email": "graham@alt-three.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Markdown Is A CommonMark Wrapper For Laravel",
|
||||||
|
"keywords": [
|
||||||
|
"Graham Campbell",
|
||||||
|
"GrahamCampbell",
|
||||||
|
"Laravel Markdown",
|
||||||
|
"Laravel-Markdown",
|
||||||
|
"common mark",
|
||||||
|
"commonmark",
|
||||||
|
"framework",
|
||||||
|
"laravel",
|
||||||
|
"markdown"
|
||||||
|
],
|
||||||
|
"time": "2020-04-14T16:14:52+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/guzzle",
|
"name": "guzzlehttp/guzzle",
|
||||||
"version": "6.5.4",
|
"version": "6.5.4",
|
||||||
|
@@ -251,6 +251,12 @@ return [
|
|||||||
'header' => 'Application Management',
|
'header' => 'Application Management',
|
||||||
'can' => ['applications.view.all', 'applications.vote']
|
'can' => ['applications.view.all', 'applications.vote']
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'text' => 'All applications',
|
||||||
|
'url' => 'applications/staff/all',
|
||||||
|
'icon' => 'fas fa-list-ol',
|
||||||
|
'can' => 'applications.view.all'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'text' => 'Outstanding Applications',
|
'text' => 'Outstanding Applications',
|
||||||
'url' => '/applications/staff/outstanding',
|
'url' => '/applications/staff/outstanding',
|
||||||
@@ -521,6 +527,7 @@ return [
|
|||||||
'location' => 'https://cdn.jsdelivr.net/npm/fullcalendar@5.0.1/main.min.css'
|
'location' => 'https://cdn.jsdelivr.net/npm/fullcalendar@5.0.1/main.min.css'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
@@ -164,7 +164,9 @@ return [
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Package Service Providers...
|
* Package Service Providers...
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
GrahamCampbell\Markdown\MarkdownServiceProvider::class,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application Service Providers...
|
* Application Service Providers...
|
||||||
@@ -173,6 +175,7 @@ return [
|
|||||||
App\Providers\AuthServiceProvider::class,
|
App\Providers\AuthServiceProvider::class,
|
||||||
App\Providers\UUIDConversionProvider::class,
|
App\Providers\UUIDConversionProvider::class,
|
||||||
App\Providers\IPInfoProvider::class,
|
App\Providers\IPInfoProvider::class,
|
||||||
|
App\Providers\ContextAwareValidatorProvider::class,
|
||||||
// App\Providers\BroadcastServiceProvider::class,
|
// App\Providers\BroadcastServiceProvider::class,
|
||||||
App\Providers\EventServiceProvider::class,
|
App\Providers\EventServiceProvider::class,
|
||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
@@ -230,7 +233,9 @@ return [
|
|||||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||||
'View' => Illuminate\Support\Facades\View::class,
|
'View' => Illuminate\Support\Facades\View::class,
|
||||||
'UUID' => App\Facades\UUID::class,
|
'UUID' => App\Facades\UUID::class,
|
||||||
'IP' => App\Facades\IP::class
|
'IP' => App\Facades\IP::class,
|
||||||
|
'Markdown' => GrahamCampbell\Markdown\Facades\Markdown::class,
|
||||||
|
'ContextAwareValidator' => App\Facades\ContextAwareValidation::class
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
|
158
config/markdown.php
Normal file
158
config/markdown.php
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Laravel Markdown.
|
||||||
|
*
|
||||||
|
* (c) Graham Campbell <graham@alt-three.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Enable View Integration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies if the view integration is enabled so you can write
|
||||||
|
| markdown views and have them rendered as html. The following extensions
|
||||||
|
| are currently supported: ".md", ".md.php", and ".md.blade.php". You may
|
||||||
|
| disable this integration if it is conflicting with another package.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'views' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| CommonMark Extensions
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies what extensions will be automatically enabled.
|
||||||
|
| Simply provide your extension class names here.
|
||||||
|
|
|
||||||
|
| Default: []
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'extensions' => [],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Renderer Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies an array of options for rendering HTML.
|
||||||
|
|
|
||||||
|
| Default: [
|
||||||
|
| 'block_separator' => "\n",
|
||||||
|
| 'inner_separator' => "\n",
|
||||||
|
| 'soft_break' => "\n",
|
||||||
|
| ]
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'renderer' => [
|
||||||
|
'block_separator' => "\n",
|
||||||
|
'inner_separator' => "\n",
|
||||||
|
'soft_break' => "\n",
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Enable Em Tag Parsing
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies if `<em>` parsing is enabled.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'enable_em' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Enable Strong Tag Parsing
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies if `<strong>` parsing is enabled.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'enable_strong' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Enable Asterisk Parsing
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies if `*` should be parsed for emphasis.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use_asterisk' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Enable Underscore Parsing
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies if `_` should be parsed for emphasis.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use_underscore' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| HTML Input
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies how to handle untrusted HTML input.
|
||||||
|
|
|
||||||
|
| Default: 'strip'
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'html_input' => 'strip',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Allow Unsafe Links
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies whether to allow risky image URLs and links.
|
||||||
|
|
|
||||||
|
| Default: true
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'allow_unsafe_links' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Maximum Nesting Level
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option specifies the maximum permitted block nesting level.
|
||||||
|
|
|
||||||
|
| Default: INF
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'max_nesting_level' => INF,
|
||||||
|
|
||||||
|
];
|
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddDetailedDescriptionToVacancy extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('vacancies', function (Blueprint $table) {
|
||||||
|
$table->longText('vacancyFullDescription')->nullable()->after('vacancyDescription');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('vacancies', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('vacancyFullDescription');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
0
install.sh
Normal file → Executable file
0
install.sh
Normal file → Executable file
10395
package-lock.json
generated
10395
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
1
public/img/403.svg
Normal file
1
public/img/403.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 17 KiB |
1
public/img/applications_all.svg
Normal file
1
public/img/applications_all.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.1 KiB |
1
public/img/editor.svg
Normal file
1
public/img/editor.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="a5860ba0-ef67-4914-ac96-07e2ebcccb4f" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="1095.74023" height="664.03433" viewBox="0 0 1095.74023 664.03433"><title>abstract</title><rect x="701" y="661" width="394.74023" height="2" fill="#3f3d56"/><polygon points="474 429 474 216 718 216 718 0 0 0 0 643 718 643 718 429 474 429" fill="#3f3d56"/><polygon points="718 216 718 0 469 0 469 213 249 213 249 0 0 0 0 216 225 216 225 429 0 429 0 643 476 643 476 429 474 429 474 216 718 216" opacity="0.1"/><path d="M224.12988,117.98284a172.00382,172.00382,0,0,1-172,172v-172Z" transform="translate(-52.12988 -117.98284)" fill="#6c63ff"/><path d="M132.12988,117.98284a80.00357,80.00357,0,0,1-80,80v44a124.00426,124.00426,0,0,0,124-124Z" transform="translate(-52.12988 -117.98284)" opacity="0.1"/><polygon points="718 60 718 29 553 29 553 0 517 0 517 29 517 60 517 84 517 115 553 115 718 115 718 84 553 84 553 60 718 60" fill="#d0cde1"/><path d="M481.12988,448.98284a81,81,0,1,0-92,80.23639V642.98284H256.36627a81,81,0,1,0,0,22H389.12988v48h22v-48h45v-22h-45V529.21923A81.00034,81.00034,0,0,0,481.12988,448.98284Z" transform="translate(-52.12988 -117.98284)" fill="#d0cde1"/><polygon points="626.5 445.263 662.508 507.631 698.517 570 626.5 570 554.483 570 590.492 507.631 626.5 445.263" fill="#d0cde1"/><polygon points="610.5 578 538.483 578 574.492 515.631 574.742 515.198 561.5 492.263 525.492 554.631 489.483 617 561.5 617 633.517 617 611 578 610.5 578" fill="#6c63ff"/><polygon points="159 345 159 291 186 291 186 259 52 259 52 393 186 393 186 345 159 345" fill="#d0cde1"/><rect x="89" y="234" width="50" height="50" fill="#6c63ff"/><path d="M989.162,357.83165,972.618,401.5551l-59.664,20.935s-36-4-36,16c0,14.18058,43,2,43,2l78.66169-23.57271,24.816-61.44917Z" transform="translate(-52.12988 -117.98284)" fill="#ffb8b8"/><rect x="635" y="228" width="234" height="202" fill="#6c63ff"/><polygon points="747.5 289.263 783.508 351.631 819.517 414 747.5 414 675.483 414 711.492 351.631 747.5 289.263" fill="#3f3d56"/><polygon points="747.331 334.415 763.665 362.708 780 391 747.331 391 714.661 391 730.996 362.708 747.331 334.415" fill="#d0cde1"/><polygon points="747.331 242.415 763.665 270.708 780 299 747.331 299 714.661 299 730.996 270.708 747.331 242.415" fill="#d0cde1"/><path d="M1024.15387,329.42035s-16.544-2.36343-24.816,28.36116-10.63544,33.088-10.63544,33.088,48.45031,7.09029,49.632,4.72686S1048.96988,336.51064,1024.15387,329.42035Z" transform="translate(-52.12988 -117.98284)" fill="#2f2e41"/><circle cx="962.57027" cy="167.71406" r="31.9063" fill="#ffb8b8"/><path d="M1000.51957,311.69463s10.63544,27.17944,7.09029,30.72459,43.72345,8.272,43.72345,8.272,3.54515-17.72572-10.63543-28.36116c0,0-5.90858-17.72572-4.72686-21.27087S1000.51957,311.69463,1000.51957,311.69463Z" transform="translate(-52.12988 -117.98284)" fill="#ffb8b8"/><path d="M1028.88073,323.51178a85.216,85.216,0,0,0-31.9063,21.27087c-14.18058,15.36229-21.27087,20.08915-21.27087,20.08915s-16.544,5.90857-10.63544,34.26973c2.95429,14.18058.88629,30.13373-1.92028,42.54174a265.8223,265.8223,0,0,0-6.35172,58.65559v12.2473s-108.71777,228.071-72.08461,243.43328,69.72118,20.08915,72.08461,16.544,44.90517-187.89267,44.90517-187.89267,11.81715,197.34639,41.36,197.34639,77.99318-8.272,77.99318-8.272l-60.26746-236.343s14.18058-40.17831-21.27087-68.53947l-4.72686-12.99886c19.60447.01,28.56614-124.06968,8.272-134.7155C1043.06131,321.14835,1038.33445,317.6032,1028.88073,323.51178Z" transform="translate(-52.12988 -117.98284)" fill="#2f2e41"/><path d="M999.33786,387.32438l-16.544,43.72345-59.664,20.935s-36-4-36,16c0,14.18058,43,2,43,2l78.6617-23.57271,24.816-61.44918Z" transform="translate(-52.12988 -117.98284)" fill="#ffb8b8"/><ellipse cx="868.62393" cy="652.21718" rx="20.68001" ry="11.81715" fill="#2f2e41"/><ellipse cx="1026.97373" cy="652.21718" rx="20.68001" ry="11.81715" fill="#2f2e41"/><path d="M1027.01734,240.95422h-.00012a25.34145,25.34145,0,0,0-4.89258.48651,21.44172,21.44172,0,0,0-9.34021-2.15271h-.84777c-16.34473,0-29.59461,14.7901-29.59461,33.03461v.00006h5.47669l.88452-6.73224L990,272.32269h4.56226a64.57589,64.57589,0,0,0-2.119,16.55036v33.62384h8.28027l4.79395-12.45795-1.19849,12.45795h53.22314l4.35816-11.32538-1.0896,11.32538h5.99243V296.09613C1066.80311,265.64215,1048.99037,240.95422,1027.01734,240.95422Z" transform="translate(-52.12988 -117.98284)" fill="#2f2e41"/></svg>
|
After Width: | Height: | Size: 4.3 KiB |
1
public/img/placeholders.svg
Normal file
1
public/img/placeholders.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.1 KiB |
1
public/img/preview.svg
Normal file
1
public/img/preview.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.3 KiB |
1
public/js/formbuilder.js
vendored
1
public/js/formbuilder.js
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
// TODO: Add cleaner and less verbose solution found in formeditor.js
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$("#add").click(function() {
|
$("#add").click(function() {
|
||||||
var lastField = $("#buildyourform div:last");
|
var lastField = $("#buildyourform div:last");
|
||||||
|
19
public/js/formeditor.js
vendored
Normal file
19
public/js/formeditor.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
// reminder: use vuejs instead, this is still an ugly and cheap solution
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
var fieldID = 0;
|
||||||
|
var wrapper = $('.field-container');
|
||||||
|
var newBtn = $('#add');
|
||||||
|
|
||||||
|
$(newBtn).click(function(e){
|
||||||
|
e.preventDefault()
|
||||||
|
fieldID++;
|
||||||
|
|
||||||
|
$(wrapper).append('<div id=group' + fieldID + '><input type="text" name="newFieldID' + fieldID + '[]" class="form-control" />');
|
||||||
|
$(wrapper).append('<select name="newFieldID' + fieldID + '[]" class="custom-select"> <option value="nil" disabled>Choose a type</option> <option value="textbox">Textbox</option> <option value="textarea">Multi line answer</option> <option value="checkbox">Checkbox</option> </select>');
|
||||||
|
//$(wrapper).append('<button type="button" class="btn btn-danger btn-sm float-right delete"><i class="fas fa-minus"></i></button></div>');
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
32
resources/views/components/form.blade.php
Normal file
32
resources/views/components/form.blade.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
@foreach($form['fields'] as $fieldName => $field)
|
||||||
|
|
||||||
|
@switch ($field['type'])
|
||||||
|
|
||||||
|
@case('textarea')
|
||||||
|
|
||||||
|
<div class="form-group mt-2 mb-2">
|
||||||
|
|
||||||
|
<label for="{{$fieldName}}">{{$field['title']}}</label>
|
||||||
|
<textarea class="form-control" rows="7" name="{{$fieldName}}" id="{{$fieldName}}" {{ ($disableFields) ? 'disabled' : '' }}>
|
||||||
|
|
||||||
|
</textarea>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('textbox')
|
||||||
|
|
||||||
|
<div class="form-group mt-2 mb-2">
|
||||||
|
|
||||||
|
<label for="{{$fieldName}}">{{$field['title']}}</label>
|
||||||
|
<input type="text" name="{{$fieldName}}" id="{{$fieldName}}" {{ ($disableFields) ? 'disabled' : '' }} class="form-control">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@break
|
||||||
|
|
||||||
|
@endswitch
|
||||||
|
|
||||||
|
@endforeach
|
74
resources/views/components/no-permission.blade.php
Normal file
74
resources/views/components/no-permission.blade.php
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
@if ($inDashboard)
|
||||||
|
<div class="row mb-4">
|
||||||
|
|
||||||
|
<div class="col-6 offset-5">
|
||||||
|
|
||||||
|
|
||||||
|
<img src="/img/403.svg" width="150px" alt="Access denied" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<!-- People find pleasure in different ways. I find it in keeping my mind clear. - Marcus Aurelius -->
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="alert alert-{{$type}}">
|
||||||
|
<h4><i class="fas fa-user-lock"></i> Access Denied</h2>
|
||||||
|
<p>
|
||||||
|
We're sorry, but you do not have permission to access this web page.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Please contact your administrator if you believe this was in error.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@else
|
||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', 'Raspberry Network | Access Denied')
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
<h4>Access Denied - HTTP 403</h4>
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="row mb-4">
|
||||||
|
|
||||||
|
<div class="col-6 offset-5">
|
||||||
|
|
||||||
|
|
||||||
|
<img src="/img/403.svg" width="150px" alt="Access denied" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="alert alert-{{$type}}">
|
||||||
|
<h4><i class="fas fa-user-lock"></i> Access Denied</h2>
|
||||||
|
<p class="text-muted">
|
||||||
|
@if (isset($slot))
|
||||||
|
{{ $slot }}
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We're sorry, but you do not have permission to access this web page.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Please contact your administrator if you believe this was in error.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@stop
|
||||||
|
@endif
|
103
resources/views/dashboard/administration/editform.blade.php
Normal file
103
resources/views/dashboard/administration/editform.blade.php
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', 'Raspberry Network | Edit From')
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
|
||||||
|
<h4>Administration / Forms / Editor</h4>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
<script src="/js/formeditor.js"></script>
|
||||||
|
<x-global-errors></x-global-errors>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col text-center">
|
||||||
|
|
||||||
|
<img src="/img/editor.svg" width="250px" alt="Editor illustration" class="img-responsive" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<form id="editForm" method="POST" action="{{ route('updateForm', ['form' => $formID]) }}">
|
||||||
|
@csrf
|
||||||
|
@method('PATCH')
|
||||||
|
<div class="card">
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
|
||||||
|
<h4>Editing {{ $title }}...</h4>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
@foreach($formStructure['fields'] as $fieldName => $field)
|
||||||
|
|
||||||
|
<div class="form-group mt-4 mb-4">
|
||||||
|
|
||||||
|
<input autocomplete="false" type="text" id="{{ $fieldName }}" class="form-control" name="{{ $fieldName }}[]" value="{{ $field['title'] }}" />
|
||||||
|
|
||||||
|
<select class="custom-select" id="{{ $fieldName }}-type" name="{{ $fieldName }}[]">
|
||||||
|
|
||||||
|
<option value="nil" disabled>Choose a type</option>
|
||||||
|
<option value="textbox" {{ ($field['type'] == 'textbox' ? 'selected' : '') }}>Textbox</option>
|
||||||
|
<option value="textarea" {{ ($field['type'] == 'textarea' ? 'selected' : '') }}>Multi line answer</option>
|
||||||
|
<option value="checkbox" {{ ($field['type'] == 'checkbox' ? 'selected' : '') }}>Checkbox</option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<div class="field-container mt-4 mb-4">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-warning ml-2" onclick="$('#editForm').submit()"><i class="fas fa-save"></i> Save & Quit</button>
|
||||||
|
<button type="button" class="btn btn-primary ml-2" id="add"><i class="fas fa-plus"></i> New field</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@stop
|
155
resources/views/dashboard/administration/editposition.blade.php
Normal file
155
resources/views/dashboard/administration/editposition.blade.php
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', 'Raspberry Network | Edit Positions')
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
|
||||||
|
<h4>Administration / Positions / Edit</h4>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
<x-global-errors>
|
||||||
|
|
||||||
|
</x-global-errors>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col center">
|
||||||
|
|
||||||
|
<h3>Vacancy Editor</h3>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
|
||||||
|
<h3 class="card-title"><i class="fas fa-clipboard"></i> {{ $vacancy->vacancyName }}</h3>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
<p class="text-muted"><i class="fas fa-question-circle"></i> For consistency purposes, grayed out fields can't be edited.</p>
|
||||||
|
|
||||||
|
<form method="POST" id="editPositionForm" action="{{ route('updatePosition', ['position' => $vacancy->id]) }}">
|
||||||
|
|
||||||
|
@csrf
|
||||||
|
@method('PATCH')
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
|
||||||
|
<label for="vacancyName">Vacancy Name</label>
|
||||||
|
<input type="text" value="{{ $vacancy->vacancyName }}" class="form-control" disabled />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<label for="vacancyDescription">Vacancy description</label>
|
||||||
|
<input type="vacancyDescription" class="form-control" name="vacancyDescription" value="{{ $vacancy->vacancyDescription }}" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<!-- skipping the accessor for obvious reasons -->
|
||||||
|
<label for="vacanyDetails">Vacancy details</label>
|
||||||
|
<textarea name="vacancyFullDescription" class="form-control" placeholder="{{ (is_null($vacancy->vacancyFullDescription)) ? 'No details yet. Add some!' : '' }}" rows="20">{{ $vacancy->getAttributes()['vacancyFullDescription'] }}</textarea>
|
||||||
|
<span class="text-muted"><i class="fab fa-markdown"></i> Markdown supported</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<label for "permissionGroupName">Permission Group</label>
|
||||||
|
<input type="text" class="form-control" value="{{ $vacancy->permissionGroupName }}" id="permissionGroupName" disabled />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<label for "discordRoleID">Discord Role ID</label>
|
||||||
|
<input type="text" class="form-control" value="{{ $vacancy->discordRoleID }}" id="discordRoleID" disabled />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<label for "currentForm">Current Form (uneditable)</label>
|
||||||
|
<input type="text" class="form-control" value="{{ $vacancy->forms->formName }}" id="currentForm" disabled />
|
||||||
|
|
||||||
|
<label for "remainingSlots">Remaining slots</label>
|
||||||
|
<input type="text" class="form-control" value="{{ $vacancy->vacancyCount }}" id="remainingSlots" name="vacancyCount" />
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-warning" onclick="$('#editPositionForm').submit()"><i class="fas fa-edit"></i> Save Changes</button>
|
||||||
|
<button type="button" class="btn btn-danger" onclick="window.location.href='{{ route('showPositions') }}'"><i class="fas fa-times"></i> Cancel</button>
|
||||||
|
|
||||||
|
@if($vacancy->vacancyStatus == 'OPEN')
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('updatePositionAvailability', ['id' => $vacancy->id, 'status' => 'close']) }}" style="display: inline">
|
||||||
|
@method('PATCH')
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="ml-4 btn btn-danger"><i class="fas fa-ban"></i> Close Position</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@stop
|
@@ -0,0 +1,79 @@
|
|||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', 'Raspberry Network | Application Form Preview')
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
|
||||||
|
<h4>Administration / Form Builder / Preview</h4>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
<x-global-errors></x-global-errors>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-6 offset-4">
|
||||||
|
|
||||||
|
<img src="/img/preview.svg" width="250px" alt="Form preview illustration" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-4">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<div class="alert alert-success">
|
||||||
|
|
||||||
|
<h5><i class="fas fa-eye"></i> This is how your form looks like to applicants</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You may edit it and add more fields later.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
|
||||||
|
<h3>{{ $title }}'s form</h2>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
@component('components.form', ['form' => $form, 'disableFields' => true])
|
||||||
|
|
||||||
|
@endcomponent
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-footer text-center">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-success ml-2" onclick="window.location.href='{{ route('showForms') }}'"><i class="fas fa-chevron-left"></i> Go back</button>
|
||||||
|
<button type="button" class="btn btn-warning ml-2" onclick="window.location.href='{{ route('editForm', ['form' => $formID]) }}'"><i class="far fa-edit"></i> Edit</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@stop
|
@@ -38,6 +38,7 @@
|
|||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>Form Title</th>
|
<th>Form Title</th>
|
||||||
<th>Created On</th>
|
<th>Created On</th>
|
||||||
|
<th>Updated On</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@
|
|||||||
<td>{{$form->id}}</td>
|
<td>{{$form->id}}</td>
|
||||||
<td>{{$form->formName}}</td>
|
<td>{{$form->formName}}</td>
|
||||||
<td>{{$form->created_at}}</td>
|
<td>{{$form->created_at}}</td>
|
||||||
|
<td>{{ $form->updated_at }}</td>
|
||||||
<td>
|
<td>
|
||||||
<form style="display: inline-block; white-space: nowrap" action="{{route('destroyForm', ['id' => $form->id])}}" method="POST">
|
<form style="display: inline-block; white-space: nowrap" action="{{route('destroyForm', ['id' => $form->id])}}" method="POST">
|
||||||
|
|
||||||
@@ -59,7 +61,7 @@
|
|||||||
|
|
||||||
<button type="submit" class="btn btn-sm btn-danger mr-2"><i class="fa fa-trash"></i> Delete</button>
|
<button type="submit" class="btn btn-sm btn-danger mr-2"><i class="fa fa-trash"></i> Delete</button>
|
||||||
</form>
|
</form>
|
||||||
<button type="button" class="btn btn-sm btn-success"><i class="fa fa-eye"></i> Preview</button>
|
<button type="button" class="btn btn-sm btn-success" onclick="window.location.href='{{ route('previewForm', ['form' => $form->id]) }}'"><i class="fa fa-eye"></i> Preview</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
@@ -4,7 +4,11 @@
|
|||||||
|
|
||||||
@section('content_header')
|
@section('content_header')
|
||||||
|
|
||||||
<h4>Administration / Open Positions</h4>
|
@if (Auth::user()->hasAnyRole('admin', 'hiringManager'))
|
||||||
|
<h4>Administration / Open Positions</h4>
|
||||||
|
@else
|
||||||
|
<h4>Application Access Denied</h4>
|
||||||
|
@endif
|
||||||
|
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
@@ -33,7 +37,8 @@
|
|||||||
@stop
|
@stop
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
@if (Auth::user()->hasAnyRole('admin', 'hiringManager'))
|
||||||
|
<!-- todo: switch to modal component -->
|
||||||
<div class="modal fade" tabindex="-1" id="newVacancyForm" role="dialog" aria-labelledby="modalFormLabel" aria-hidden="true">
|
<div class="modal fade" tabindex="-1" id="newVacancyForm" role="dialog" aria-labelledby="modalFormLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@@ -55,6 +60,9 @@
|
|||||||
<label for="vacancyDescription">Vacancy Description</label>
|
<label for="vacancyDescription">Vacancy Description</label>
|
||||||
<input type="text" id="vacancyDescription" name="vacancyDescription" class="form-control">
|
<input type="text" id="vacancyDescription" name="vacancyDescription" class="form-control">
|
||||||
|
|
||||||
|
<label for="vacancyFullDescription">Vacancy Details</label>
|
||||||
|
<textarea name="vacancyFullDescription" class="form-control" rel="txtTooltip" title="Add things like admission requirements, rank resposibilities and roles, and anything else you feel is necessary" data-toggle="tooltip" data-placement="bottom"></textarea>
|
||||||
|
<span class="right text-muted"><i class="fab fa-markdown"></i> Markdown supported</span>
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -153,9 +161,8 @@
|
|||||||
<thead>
|
<thead>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<th>Name</th>
|
||||||
<th>Vacancy Name</th>
|
<th>Description</th>
|
||||||
<th>Vacancy Description</th>
|
|
||||||
<th>Discord Role ID</th>
|
<th>Discord Role ID</th>
|
||||||
<th>Perm. Group Name</th>
|
<th>Perm. Group Name</th>
|
||||||
<th>Open Slots</th>
|
<th>Open Slots</th>
|
||||||
@@ -171,8 +178,6 @@
|
|||||||
@foreach($vacancies as $vacancy)
|
@foreach($vacancies as $vacancy)
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
<td>{{$vacancy->id}}</td>
|
|
||||||
<td>{{$vacancy->vacancyName}}</td>
|
<td>{{$vacancy->vacancyName}}</td>
|
||||||
<td>{{substr($vacancy->vacancyDescription, 0, 20)}}...</td>
|
<td>{{substr($vacancy->vacancyDescription, 0, 20)}}...</td>
|
||||||
<td><span class="badge badge-success">{{$vacancy->discordRoleID}}</span></td>
|
<td><span class="badge badge-success">{{$vacancy->discordRoleID}}</span></td>
|
||||||
@@ -185,20 +190,23 @@
|
|||||||
@endif
|
@endif
|
||||||
<td>{{$vacancy->created_at}}</td>
|
<td>{{$vacancy->created_at}}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-sm btn-warning" onclick="window.location.href='{{ route('editPosition', ['position' => $vacancy->id]) }}'"><i class="fas fa-edit"></i></button>
|
||||||
|
|
||||||
@if ($vacancy->vacancyStatus == 'OPEN')
|
@if ($vacancy->vacancyStatus == 'OPEN')
|
||||||
|
|
||||||
<form action="{{route('updatePositionAvailability', ['status' => 'close', 'id' => $vacancy->id])}}" method="POST" id="closePosition">
|
<form action="{{route('updatePositionAvailability', ['status' => 'close', 'id' => $vacancy->id])}}" method="POST" id="closePosition" style="display: inline">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
<button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-ban"></i> Close</button>
|
<button type="submit" class="btn btn-sm btn-danger"><i class="fa fa-ban"></i></button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@else
|
@else
|
||||||
|
|
||||||
<form action="{{route('updatePositionAvailability', ['status' => 'open', 'id' => $vacancy->id])}}" method="POST" id="openPosition">
|
<form action="{{route('updatePositionAvailability', ['status' => 'open', 'id' => $vacancy->id])}}" method="POST" id="openPosition" style="display: inline">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PATCH')
|
@method('PATCH')
|
||||||
<button type="submit" class="btn btn-sm btn-success"><i class="fa fa-check"></i> Open</button>
|
<button type="submit" class="btn btn-sm btn-success"><i class="fa fa-check"></i></button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
@@ -232,5 +240,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@else
|
||||||
|
<x-no-permission type="danger"></x-no-permission>
|
||||||
|
@endif
|
||||||
@stop
|
@stop
|
||||||
|
@@ -93,38 +93,10 @@
|
|||||||
|
|
||||||
<form action="{{route('saveApplicationForm', ['vacancySlug' => $vacancy->vacancySlug])}}" method="POST" id="submitApplicationForm">
|
<form action="{{route('saveApplicationForm', ['vacancySlug' => $vacancy->vacancySlug])}}" method="POST" id="submitApplicationForm">
|
||||||
@csrf
|
@csrf
|
||||||
@foreach($preprocessedForm['fields'] as $fieldName => $field)
|
|
||||||
|
|
||||||
@switch ($field['type'])
|
@component('components.form', ['form' => $preprocessedForm, 'disableFields' => false])
|
||||||
|
|
||||||
@case('textarea')
|
@endcomponent
|
||||||
|
|
||||||
<div class="form-group mt-2 mb-2">
|
|
||||||
|
|
||||||
<label for="{{$fieldName}}">{{$field['title']}}</label>
|
|
||||||
<textarea class="form-control" rows="7" name="{{$fieldName}}" id="{{$fieldName}}">
|
|
||||||
|
|
||||||
</textarea>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@break
|
|
||||||
|
|
||||||
@case('textbox')
|
|
||||||
|
|
||||||
<div class="form-group mt-2 mb-2">
|
|
||||||
|
|
||||||
<label for="{{$fieldName}}">{{$field['title']}}</label>
|
|
||||||
<input type="text" name="{{$fieldName}}" id="{{$fieldName}}" class="form-control">
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@break
|
|
||||||
|
|
||||||
@endswitch
|
|
||||||
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
243
resources/views/dashboard/appmanagement/all.blade.php
Normal file
243
resources/views/dashboard/appmanagement/all.blade.php
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
@extends('adminlte::page')
|
||||||
|
|
||||||
|
@section('title', 'Raspberry Network | Profile')
|
||||||
|
|
||||||
|
@section('content_header')
|
||||||
|
|
||||||
|
<h4>Application Management / All Applications</h4>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('js')
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/js/app.js"></script>
|
||||||
|
<x-global-errors></x-global-errors>
|
||||||
|
|
||||||
|
@stop
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
|
||||||
|
|
||||||
|
@foreach($applications as $application)
|
||||||
|
|
||||||
|
<x-modal id="deletionConfirmationModal-{{ $application->id }}" modal-label="deletion-{{ $application->id }}" modal-title="Are you sure?" include-close-button="true">
|
||||||
|
|
||||||
|
<h4><i class="fas fa-exclamation-triangle"></i> Really delete this?</h3>
|
||||||
|
<p>
|
||||||
|
This action is <b>IRREVERSBILE.</b>
|
||||||
|
</p>
|
||||||
|
<p>Comments, appointments and any votes attached to this application WILL be deleted too. Please make sure this application really needs to be deleted.</p>
|
||||||
|
|
||||||
|
<x-slot name="modalFooter">
|
||||||
|
|
||||||
|
<form method="POST" action="{{ route('deleteApplication', ['application' => $application->id]) }}">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit" class="btn btn-danger"><i class="fas fa-check-double"></i> Confirm</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="callout callout-info">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-3">
|
||||||
|
|
||||||
|
<img src="/img/applications_all.svg" alt="Applications illustration" class="img-responsive" width="200px"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<h3><i class="fas fa-info-circle"></i> You're looking at all applications ever received</h3>
|
||||||
|
<p>
|
||||||
|
Here, you have quick and easy access to all applications ever received by the system.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row mt-5">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<!-- MAIN CONTENT - APPS AND PICS -->
|
||||||
|
|
||||||
|
<div class="card-header">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-3">
|
||||||
|
<h3>All applications</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="navbtn right" style="whitespace: nowrap">
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" onclick="window.location.href='{{ route('staffPendingApps') }}'"><i class="far fa-folder-open"></i> Outstanding Applications</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" onclick="window.location.href='{{ route('pendingInterview') }}'"><i class="fas fa-microphone-alt"></i> Interview Queue</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" onclick="window.location.href='{{ route('peerReview') }}'"><i class="fas fa-search"></i> Peer Review</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col-3 center">
|
||||||
|
|
||||||
|
<img src="/img/placeholders.svg" alt="Placeholder illustration" class="img-responsive" width="200px"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
@if (!$applications->isEmpty())
|
||||||
|
|
||||||
|
<table class="table table-borderless" style="whitespace: nowrap">
|
||||||
|
|
||||||
|
<thead>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Applicant</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
@foreach($applications as $application)
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>{{ $application->id }}</td>
|
||||||
|
<td><a href="{{ route('showSingleProfile', ['user' => $application->user->id]) }}">{{ $application->user->name }}</a></td>
|
||||||
|
<td>
|
||||||
|
@switch($application->applicationStatus)
|
||||||
|
|
||||||
|
@case('STAGE_SUBMITTED')
|
||||||
|
|
||||||
|
<span class="badge badge-primary"><i class="far fa-clock"></i> Outstanding (Submitted)</span>
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('STAGE_PEERAPPROVAL')
|
||||||
|
|
||||||
|
<span class="badge badge-warning"><i class="fas fa-vote-yea"></i> Peer Approval</span>
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('STAGE_INTERVIEW')
|
||||||
|
|
||||||
|
<span class="badge badge-warning"><i class="fas fa-microphone-alt"></i> Interview</span>
|
||||||
|
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('STAGE_INTERVIEW_SCHEDULED')
|
||||||
|
|
||||||
|
<span class="badge badge-warning"><i class="far fa-clock"></i>Interview Scheduled</span>
|
||||||
|
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('APPROVED')
|
||||||
|
|
||||||
|
<span class="badge badge-success"><i class="fas fa-check"></i> Approved</span>
|
||||||
|
|
||||||
|
@break
|
||||||
|
|
||||||
|
@case('DENIED')
|
||||||
|
|
||||||
|
<span class="badge badge-danger"><i class="fas fa-times"></i> Denied</span>
|
||||||
|
|
||||||
|
@break;
|
||||||
|
|
||||||
|
@default
|
||||||
|
<span class="badge badge-secondary"><i class="fas fa-question-circle"></i> Unknown</span>
|
||||||
|
|
||||||
|
|
||||||
|
@endswitch
|
||||||
|
</td>
|
||||||
|
<td>{{ $application->created_at }}</td>
|
||||||
|
<td>
|
||||||
|
<button type="button" class="btn btn-success btn-sm" onclick="window.location.href='{{ route('showUserApp', ['id' => $application->id]) }}'"><i class="fas fa-eye"></i> View</button>
|
||||||
|
<button type="button" class="btn btn-danger btn-sm ml-2" onclick="$('#deletionConfirmationModal-{{ $application->id }}').modal('show')"><i class="fa fa-trash"></i> Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
@else
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
|
||||||
|
<h3><i class="fas fa-question-circle"></i> There are no applications here</h3>
|
||||||
|
<p>
|
||||||
|
We couldn't find any applications. Maybe no one has applied yet?
|
||||||
|
Please try again later.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- end main content card -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (!$applications->isEmpty() && isset($applications->links))
|
||||||
|
|
||||||
|
<div class="card-footer">
|
||||||
|
|
||||||
|
{{ $applications->links }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@stop
|
@@ -14,6 +14,38 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
|
@if (!$vacancies->isEmpty())
|
||||||
|
|
||||||
|
@foreach($vacancies as $vacancy)
|
||||||
|
|
||||||
|
<x-modal id="{{ $vacancy->vacancySlug . '-details' }}" modal-label="{{ $vacancy->vacancySlug . '-details-label' }}" modal-title="Vacancy details" include-close-button="true">
|
||||||
|
|
||||||
|
@if (is_null($vacancy->vacancyFullDescription))
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
|
||||||
|
<h3><i class="fas fa-question-circle"></i> There don't seem to be any details</h3>
|
||||||
|
<p>
|
||||||
|
This vacancy does not have any details yet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
|
||||||
|
{!! $vacancy->vacancyFullDescription !!}
|
||||||
|
<p class="text-sm text-muted">
|
||||||
|
Last updated @ {{ $vacancy->updated_at }}
|
||||||
|
</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<x-slot name="modalFooter"></x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="row mt-5">
|
<div class="row mt-5">
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@@ -190,7 +222,7 @@
|
|||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
|
|
||||||
<button type="button" class="btn btn-primary btn-sm" onclick="window.location.href='{{ route('renderApplicationForm', ['vacancySlug' => $vacancy->vacancySlug]) }}'">Apply</button>
|
<button type="button" class="btn btn-primary btn-sm" onclick="window.location.href='{{ route('renderApplicationForm', ['vacancySlug' => $vacancy->vacancySlug]) }}'">Apply</button>
|
||||||
<button type="button" class="btn btn-warning btn-sm">Learn More</button>
|
<button type="button" class="btn btn-warning btn-sm" onclick="$('#{{ $vacancy->vacancySlug }}-details').modal('show')">Learn More</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -75,6 +75,18 @@
|
|||||||
|
|
||||||
@endhasrole
|
@endhasrole
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
|
||||||
|
<div class="alert alert-warning alert-dismissible">
|
||||||
|
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>
|
||||||
|
<strong>Reminder:</strong> If this form has been updated, new fields and updated questions will not show up here!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
|
@@ -2,6 +2,40 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
|
||||||
|
@if(!$positions->isEmpty())
|
||||||
|
|
||||||
|
<!-- todo: details component -->
|
||||||
|
|
||||||
|
@foreach($positions as $position)
|
||||||
|
<x-modal id="{{ $position->vacancySlug . '-details' }}" modal-label="{{ $position->vacancySlug . '-details-label' }}" modal-title="Opening details" include-close-button="true">
|
||||||
|
|
||||||
|
@if (is_null($position->vacancyFullDescription))
|
||||||
|
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
|
||||||
|
<h3><i class="fas fa-question-circle"></i> There don't seem to be any details</h3>
|
||||||
|
<p>
|
||||||
|
This opening does not have any details yet.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
|
||||||
|
{!! $position->vacancyFullDescription !!}
|
||||||
|
<p class="text-sm text-muted">
|
||||||
|
Last updated @ {{ $position->updated_at }}
|
||||||
|
</p>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<x-slot name="modalFooter"></x-slot>
|
||||||
|
|
||||||
|
</x-modal>
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
@endif
|
||||||
|
|
||||||
<!--Main Layout-->
|
<!--Main Layout-->
|
||||||
<main class="py-5">
|
<main class="py-5">
|
||||||
|
|
||||||
@@ -57,6 +91,7 @@
|
|||||||
|
|
||||||
@guest
|
@guest
|
||||||
<button type="button" class="btn btn-success" onclick="window.location.href='{{route('renderApplicationForm', ['vacancySlug' => $position->vacancySlug])}}'">Apply</button>
|
<button type="button" class="btn btn-success" onclick="window.location.href='{{route('renderApplicationForm', ['vacancySlug' => $position->vacancySlug])}}'">Apply</button>
|
||||||
|
<button type="button" class="btn btn-info" onclick="$('#{{ $position->vacancySlug }}-details').modal('show')">Learn more</button>
|
||||||
@endguest
|
@endguest
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -40,7 +40,6 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){
|
|||||||
->name('showUserApps')
|
->name('showUserApps')
|
||||||
->middleware('eligibility');
|
->middleware('eligibility');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/view/{id}', 'ApplicationController@showUserApp')
|
Route::get('/view/{id}', 'ApplicationController@showUserApp')
|
||||||
->name('showUserApp');
|
->name('showUserApp');
|
||||||
|
|
||||||
@@ -58,16 +57,27 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){
|
|||||||
Route::patch('/update/{id}/{newStatus}', 'ApplicationController@updateApplicationStatus')
|
Route::patch('/update/{id}/{newStatus}', 'ApplicationController@updateApplicationStatus')
|
||||||
->name('updateApplicationStatus');
|
->name('updateApplicationStatus');
|
||||||
|
|
||||||
|
Route::delete('{application}/delete', 'ApplicationController@delete')
|
||||||
|
->name('deleteApplication');
|
||||||
|
|
||||||
|
|
||||||
|
Route::get('/staff/all', 'ApplicationController@showAllApps')
|
||||||
|
->name('allApplications');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/staff/outstanding', 'ApplicationController@showAllPendingApps')
|
Route::get('/staff/outstanding', 'ApplicationController@showAllPendingApps')
|
||||||
->name('staffPendingApps');
|
->name('staffPendingApps');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/staff/peer-review', 'ApplicationController@showPeerReview')
|
Route::get('/staff/peer-review', 'ApplicationController@showPeerReview')
|
||||||
->name('peerReview');
|
->name('peerReview');
|
||||||
|
|
||||||
|
|
||||||
Route::get('/staff/pending-interview', 'ApplicationController@showPendingInterview')
|
Route::get('/staff/pending-interview', 'ApplicationController@showPendingInterview')
|
||||||
->name('pendingInterview');
|
->name('pendingInterview');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Route::post('{id}/staff/vote', 'VoteController@vote')
|
Route::post('{id}/staff/vote', 'VoteController@vote')
|
||||||
->name('voteApplication');
|
->name('voteApplication');
|
||||||
|
|
||||||
@@ -161,6 +171,13 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){
|
|||||||
->name('savePosition');
|
->name('savePosition');
|
||||||
|
|
||||||
|
|
||||||
|
Route::get('positions/edit/{position}', 'VacancyController@edit')
|
||||||
|
->name('editPosition');
|
||||||
|
|
||||||
|
Route::patch('positions/update/{position}', 'VacancyController@update')
|
||||||
|
->name('updatePosition');
|
||||||
|
|
||||||
|
|
||||||
Route::patch('positions/availability/{status}/{id}', 'VacancyController@updatePositionAvailability')
|
Route::patch('positions/availability/{status}/{id}', 'VacancyController@updatePositionAvailability')
|
||||||
->name('updatePositionAvailability');
|
->name('updatePositionAvailability');
|
||||||
|
|
||||||
@@ -177,6 +194,15 @@ Route::group(['middleware' => ['auth', 'forcelogout']], function(){
|
|||||||
Route::get('forms', 'FormController@index')
|
Route::get('forms', 'FormController@index')
|
||||||
->name('showForms');
|
->name('showForms');
|
||||||
|
|
||||||
|
Route::get('forms/preview/{form}', 'FormController@preview')
|
||||||
|
->name('previewForm');
|
||||||
|
|
||||||
|
Route::get('forms/edit/{form}', 'FormController@edit')
|
||||||
|
->name('editForm');
|
||||||
|
|
||||||
|
Route::patch('forms/update/{form}', 'FormController@update')
|
||||||
|
->name('updateForm');
|
||||||
|
|
||||||
|
|
||||||
Route::get('devtools', 'DevToolsController@index')
|
Route::get('devtools', 'DevToolsController@index')
|
||||||
->name('devTools');
|
->name('devTools');
|
||||||
|
Reference in New Issue
Block a user