This commit is contained in:
Joey Kimsey
2024-12-02 17:43:55 -05:00
parent 113499254b
commit de5530b1e3
95 changed files with 3192 additions and 509 deletions

View File

@ -0,0 +1,103 @@
<?php
/**
* app/plugins/resume/controllers/admin/resume.php
*
* This is the Resume admin controller.
*
* @package TP Resume
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Admin;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Houdini\Classes\Navigation;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Classes\AdminController;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Models\Positions;
class Resume extends AdminController {
public static $positions;
public function __construct() {
parent::__construct();
self::$positions = new Positions;
self::$title = 'Admin - Resume';
$view = Navigation::activePageSelect( 'nav.admin', '/admin/resume' );
Components::set( 'ADMINNAV', $view );
}
public function index( $data = null ) {
Views::view( 'resume.admin.list', self::$positions->listPaginated() );
}
public function create( $data = null ) {
if ( !Input::exists( 'submit' ) ) {
return Views::view( 'resume.admin.create' );
}
if ( !Forms::check( 'newPosition' ) ) {
Issues::add( 'error', [ 'There was an error with your request.' => Check::userErrors() ] );
return $this->index();
}
$result = self::$positions->create( Input::post( 'name' ), Input::post( 'position' ), Input::post( 'start' ), Input::post( 'end' ), Input::post( 'details' ) );
if ( $result ) {
Issues::add( 'success', 'Your position has been created.' );
return $this->index();
} else {
Issues::add( 'error', [ 'There was an unknown error submitting your data.' => Check::userErrors() ] );
return $this->index();
}
}
public function edit( $data = null ) {
if ( !Input::exists( 'submit' ) ) {
return Views::view( 'resume.admin.edit', self::$positions->findById( $data ) );
}
if ( !Forms::check( 'editPosition' ) ) {
Issues::add( 'error', [ 'There was an error with your form.' => Check::userErrors() ] );
return $this->index();
}
$fields = [
'name' => Input::post( 'name' ),
'position' => Input::post( 'position' ),
'start' => Input::post( 'start' ),
'end' => Input::post( 'end' ),
'details' => Input::post( 'details' ),
];
if ( self::$positions->update( $data, $fields ) ) {
Issues::add( 'success', 'Position Updated.' );
return $this->index();
}
Issues::add( 'error', 'There was an error with your request.' );
$this->index();
}
public function view( $data = null ) {
$positionData = self::$positions->findById( $data );
if ( $positionData !== false ) {
return Views::view( 'resume.admin.view', $positionData );
}
Issues::add( 'error', 'Position not found.' );
$this->index();
}
public function delete( $data = null ) {
if ( $data == null ) {
if ( Input::exists( 'P_' ) ) {
$data = Input::post( 'P_' );
}
}
if ( !self::$positions->delete( (array) $data ) ) {
Issues::add( 'error', 'There was an error with your request.' );
} else {
Issues::add( 'success', 'Position has been deleted' );
}
$this->index();
}
}

View File

@ -0,0 +1,58 @@
<?php
/**
* app/plugins/resume/controllers/resume.php
*
* This is the bug reports controller.
*
* @package TP Resume
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Houdini\Classes\Issues;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Models\Positions;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Houdini\Classes\Template;
class Resume extends Controller {
protected static $positions;
public function index() {
self::$positions = new Positions;
self::$title = '{SITENAME} - Resume';
self::$pageDescription = 'Its not the longest resume in the world, but I\'m certainly proud of it.';
$positions = self::$positions->listPaginated();
if ( false == $positions ) {
Issues::add( 'error', 'Well, this is embarrassing, surely he wouldn\'t just have no resume..... right.... Dave? ... erm Joey?' );
return;
} else {
Components::set( 'RESUME_NAV', Views::simpleView( 'resume.nav') );
Components::set( 'RESUME_DOWNLOADS', Views::simpleView( 'resume.download') );
if ( !Input::exists( 'view' ) ) {
return Views::view( 'resume.resume', $positions );
} else {
Components::append( 'TEMPLATE_CSS_INCLUDES', Template::parse('<link rel="stylesheet" href="{ROOT_URL}app/plugins/resume/css/timeline.css" />') );
$side = 'left';
foreach ($positions as $key => $position) {
$position->side = $side; // Add the new entry for side
$side = ($side === 'left') ? 'right' : 'left'; // Alternate between left and right
}
return Views::view( 'resume.timeline', $positions );
}
}
}
public function test() {
self::$positions = new Positions;
self::$title = '{SITENAME} - Resume';
self::$pageDescription = 'Its not the longest resume in the world, but I\'m certainly proud of it.';
return Views::view( 'resume.test' );
}
}

View File

@ -0,0 +1,132 @@
* {
box-sizing: border-box;
}
body {
/* background-color: #474e5d;
font-family: Helvetica, sans-serif; */
}
/* The actual timeline (the vertical ruler) */
.resume-timeline {
position: relative;
max-width: 1200px;
margin: 0 auto;
}
/* The actual timeline (the vertical ruler) */
.resume-timeline::after {
content: '';
position: absolute;
width: 6px;
background-color: #B5B5B5;
top: 0;
bottom: 0;
left: 50%;
margin-left: -3px;
}
/* Container around content */
.timeline-container {
padding: 10px 40px;
position: relative;
background-color: inherit;
width: 50%;
}
/* The circles on the timeline */
.timeline-container::after {
content: '';
position: absolute;
width: 25px;
height: 25px;
right: -13px;
background-color: #337ab7;
border: 4px solid #FF9F55;
top: 15px;
border-radius: 50%;
z-index: 1;
}
/* Place the container to the left */
.left {
left: 0;
}
/* Place the container to the right */
.right {
left: 50%;
}
/* Add arrows to the left container (pointing right) */
.left::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
right: 30px;
border: medium solid white;
border-width: 10px 0 10px 10px;
border-color: transparent transparent transparent white;
}
/* Add arrows to the right container (pointing left) */
.right::before {
content: " ";
height: 0;
position: absolute;
top: 22px;
width: 0;
z-index: 1;
left: 30px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
/* Fix the circle for containers on the right side */
.right::after {
left: -11px;
}
/* The actual content */
.timeline-content {
padding: 20px 30px;
background-color: white;
position: relative;
border-radius: 6px;
}
/* Media queries - Responsive timeline on screens less than 600px wide */
@media screen and (max-width: 600px) {
/* Place the timelime to the left */
.resume-timeline::after {
left: 31px;
}
/* Full-width containers */
.timeline-container {
width: 100%;
padding-left: 70px;
padding-right: 25px;
}
/* Make sure that all arrows are pointing leftwards */
.timeline-container::before {
left: 60px;
border: medium solid white;
border-width: 10px 10px 10px 0;
border-color: transparent white transparent transparent;
}
/* Make sure all circles are at the same spot */
.left::after, .right::after {
left: 15px;
}
/* Make all right containers behave like the left ones */
.right {
left: 0%;
}
}

View File

@ -0,0 +1,87 @@
<?php
/**
* app/plugins/resume/forms.php
*
* This houses all of the form checking functions for this plugin.
*
* @package TP Resume
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins\Resume;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Classes\Forms;
class ResumeForms extends Forms {
/**
* Adds these functions to the form list.
*/
public function __construct() {
self::addHandler( 'newPosition', __CLASS__, 'newPosition' );
self::addHandler( 'editPosition', __CLASS__, 'editPosition' );
}
/**
* Validates the new position post form.
*
* @return {bool}
*/
public static function newPosition() {
if ( !Input::exists( 'name' ) ) {
self::addUserError( 'You must specify name' );
return false;
}
if ( !Input::exists( 'position' ) ) {
self::addUserError( 'You must specify position' );
return false;
}
if ( !Input::exists( 'start' ) ) {
self::addUserError( 'You must specify start' );
return false;
}
if ( !Input::exists( 'end' ) ) {
self::addUserError( 'You must specify end' );
return false;
}
if ( !Input::exists( 'details' ) ) {
self::addUserError( 'You must specify details' );
return false;
}
return true;
}
/**
* Validates the edit position post form.
*
* @return {bool}
*/
public static function editPosition() {
if ( !Input::exists( 'name' ) ) {
self::addUserError( 'You must specify name' );
return false;
}
if ( !Input::exists( 'position' ) ) {
self::addUserError( 'You must specify position' );
return false;
}
if ( !Input::exists( 'start' ) ) {
self::addUserError( 'You must specify start' );
return false;
}
if ( !Input::exists( 'end' ) ) {
self::addUserError( 'You must specify end' );
return false;
}
if ( !Input::exists( 'details' ) ) {
self::addUserError( 'You must specify details' );
return false;
}
return true;
}
}
new ResumeForms;

View File

@ -0,0 +1,88 @@
<?php
/**
* app/plugins/resume/models/positions.php
*
* This class is used for the manipulation of the positions database table.
*
* @package TP Resume
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Models;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Functions\Check;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Classes\DatabaseModel;
use TheTempusProject\Plugins\Resume as Plugin;
class Positions extends DatabaseModel {
public $tableName = 'positions';
public $databaseMatrix = [
[ 'name', 'varchar', '128' ],
[ 'position', 'varchar', '128' ],
[ 'start', 'varchar', '16' ],
[ 'end', 'varchar', '16' ],
[ 'details', 'text', '' ],
];
public $plugin;
/**
* The model constructor.
*/
public function __construct() {
parent::__construct();
$this->plugin = new Plugin;
}
public function create( $name, $position, $start, $end, $details ) {
if ( !$this->plugin->checkEnabled() ) {
Debug::info( 'Resume is disabled in the config.' );
return false;
}
$fields = [
'name' => $name,
'position' => $position,
'start' => $start,
'end' => $end,
'details' => $details,
];
if ( !self::$db->insert( $this->tableName, $fields ) ) {
Debug::info( 'Position::create - failed to insert to db' );
return false;
}
return self::$db->lastId();
}
public function filter( $postArray, $params = [] ) {
foreach ( $postArray as $instance ) {
if ( !is_object( $instance ) ) {
$instance = $postArray;
$end = true;
}
$instance->prettyStart = $instance->start;
$instance->prettyEnd = $instance->end;
$out[] = $instance;
if ( !empty( $end ) ) {
$out = $out[0];
break;
}
}
return $out;
}
public function update( $id, $fields ) {
if ( !Check::id( $id ) ) {
Debug::info( 'Positions:update: illegal ID.' );
return false;
}
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
// new CustomException( 'positionUpdate' );
Debug::error( "Positions:update: $id not updated: $fields" );
return false;
}
return true;
}
}

View File

@ -0,0 +1,44 @@
<?php
/**
* app/plugins/resume/plugin.php
*
* This houses all of the main plugin info and functionality.
*
* @package TP Resume
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Plugins;
use TheTempusProject\Classes\Plugin;
class Resume extends Plugin {
public $pluginName = 'TP Resume';
public $pluginAuthor = 'JoeyK';
public $pluginWebsite = 'https://TheTempusProject.com';
public $modelVersion = '1.0';
public $pluginVersion = '3.0';
public $pluginDescription = 'A simple plugin which adds management for a resume.';
public $configName = 'resume';
public $configMatrix = [
'enabled' => [
'type' => 'radio',
'pretty' => 'Enable the resume Feature.',
'default' => true,
],
];
public $main_links = [
[
'text' => 'Resume',
'url' => '{ROOT_URL}resume/index',
],
];
public $admin_links = [
[
'text' => '<i class="fa fa-fw fa-support"></i> Resume',
'url' => '{ROOT_URL}admin/resume',
],
];
}

View File

@ -0,0 +1,19 @@
<h2>Resume Entry Form</h2>
<form action="#" method="POST">
<label for="name">Company Name:</label><br>
<input type="text" id="name" name="name" required><br><br>
<label for="position">Position:</label><br>
<input type="text" id="position" name="position" required><br><br>
<label for="start">Start Month/Year:</label><br>
<input type="month" id="start" name="start" required><br><br>
<label for="end">End Month/Year:</label><br>
<input type="month" id="end" name="end" required><br><br>
<label for="details">Details:</label><br>
<textarea id="details" name="details" rows="20" cols="50" required></textarea><br><br>
<input type="submit" name="submit" value="Submit">
</form>

View File

@ -0,0 +1,19 @@
<h2>Edit Resume Position</h2>
<form action="#" method="POST">
<label for="name">Company Name:</label><br>
<input type="text" id="name" name="name" value="{name}" required><br><br>
<label for="position">Position:</label><br>
<input type="text" id="position" name="position" value="{position}" required><br><br>
<label for="start">Start Month/Year:</label><br>
<input type="month" id="start" name="start" value="{start}" required><br><br>
<label for="end">End Month/Year:</label><br>
<input type="month" id="end" name="end" value="{end}" required><br><br>
<label for="details">Details:</label><br>
<textarea id="details" name="details" rows="20" cols="50" required>{details}</textarea><br><br>
<input type="submit" name="submit" value="Submit">
</form>

View File

@ -0,0 +1,43 @@
<legend>Resume Positions</legend>
{PAGINATION}
<form action="{ROOT_URL}admin/resume/delete" method="post">
<table class="table table-striped">
<thead>
<tr>
<th style="width: 30%">Name</th>
<th style="width: 20%">Position</th>
<th style="width: 10%">Start</th>
<th style="width: 10%">End</th>
<th style="width: 10%"></th>
<th style="width: 10%"></th>
<th style="width: 10%">
<INPUT type="checkbox" onchange="checkAll(this)" name="check.b" value="B_[]"/>
</th>
</tr>
</thead>
<tbody>
{LOOP}
<tr>
<td><a href="{ROOT_URL}admin/resume/view/{ID}">{name}</a></td>
<td>{position}</td>
<td>{prettyStart}</td>
<td>{prettyEnd}</td>
<td><a href="{ROOT_URL}admin/resume/edit/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
<td><a href="{ROOT_URL}admin/resume/delete/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
<td>
<input type="checkbox" value="{ID}" name="P_[]">
</td>
</tr>
{/LOOP}
{ALT}
<tr>
<td colspan="7">
No results to show.
</td>
</tr>
{/ALT}
</tbody>
</table>
<a href="{ROOT_URL}admin/resume/create" class="btn btn-sm btn-primary" role="button">Create</a>
<button name="submit" value="submit" type="submit" class="btn btn-sm btn-danger">Delete</button>
</form>

View File

@ -0,0 +1,8 @@
<legend>Resume Position</legend>
<div class="resume-position">
<h3 class="resume-position-title">{name}</h3>
<p><b>{position}</b> from <i>{prettyStart}</i> to <i>{prettyEnd}</i></p>
<div class="well">
{details}
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="col-lg-12 text-center" role="group" aria-label="Resume Downloads">
<div class="btn-group text-center" role="group" aria-label="Resume Downloads">
<h3>Download</h3>
<a href="/downloads/JoeyKimsey-resume.docx" class="btn btn-default" role="button">Word</a>
<a href="/downloads/JoeyKimsey-resume.pdf" class="btn btn-default" role="button">PDF</a>
<a href="/downloads/JoeyKimsey-resume.md" class="btn btn-default" role="button">Markdown</a>
<a href="/downloads/JoeyKimsey-resume.txt" class="btn btn-default" role="button">Text</a>
</div>
</div>

View File

@ -0,0 +1,4 @@
<div class="btn-group btn-group-justified" role="group" aria-label="Resume View Type">
<a href="?view=tiimeline" class="btn btn-default" role="button">Timeliine</a>
<a href="?" class="btn btn-default" role="button">Standard</a>
</div>

View File

@ -0,0 +1,18 @@
<h1>Resume</h1>
<hr>
{RESUME_NAV}
{LOOP}
<div class="resume-position">
<h3 class="resume-position-title">{name}</h3>
<p><b>{position}</b> from <i>{prettyStart}</i> to <i>{prettyEnd}</i></p>
<div class="well">
{details}
</div>
</div>
{/LOOP}
{ALT}
<div class="resume-position">
<p>None Found</p>
</div>
{/ALT}
{RESUME_DOWNLOADS}

View File

@ -0,0 +1,139 @@
<div class="btn-group btn-group-justified" role="group" aria-label="Resume View Type">
<a href="?view=tiimeline" class="btn btn-default" role="button">Timeline</a>
<div class="btn-group">
<button class="btn btn-default btn-lg dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Options <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
<a href="?" class="btn btn-default" role="button">Standard</a>
</div>
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" aria-label="...">
</span>
<span class="input-group-addon" id="basic-addon3">
Show / Hide the Bullshit
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon" id="basic-addon3">https://example.com/users/</span>
<input type="checkbox" aria-label="...">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" aria-label="...">
</span>
<input type="text" class="form-control" aria-label="...">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" aria-label="...">
</span>
<span class="input-group-addon" id="basic-addon3">https://example.com/users/</span>
</div>
</div>
</div>
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">@</span>
<input type="text" class="form-control" placeholder="Username" aria-describedby="basic-addon1">
</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="Recipient's username" aria-describedby="basic-addon2">
<span class="input-group-addon" id="basic-addon2">@example.com</span>
</div>
<label for="basic-url">Your vanity URL</label>
<div class="input-group">
<span class="input-group-addon" id="basic-addon3">https://example.com/users/</span>
<input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>

View File

@ -0,0 +1,22 @@
<h1>Resume</h1>
<hr>
{RESUME_NAV}
{LOOP}
<div class="resume-timeline">
<div class="timeline-container {side}">
<div class="timeline-content">
<h3 class="resume-position-title">{name}</h3>
<p><b>{position}</b> from <i>{prettyStart}</i> to <i>{prettyEnd}</i></p>
<div class="well">
{details}
</div>
</div>
</div>
</div>
{/LOOP}
{ALT}
<div class="resume-timeline">
<p>None Found</p>
</div>
{/ALT}
{RESUME_DOWNLOADS}