I graduated from high school in 2003 and initially worked in various local warehouse and manufacturing positions. From 2004 to 2010, I was employed at Fleetwood/Fleetwood RV (now REV Group, Inc.) in Decatur, IN, where I served as an electrician and Assistant Group Leader.
In September 2012, I relocated to Indianapolis to pursue a career in development and programming. I began with front-end development and progressively advanced to become a full-stack developer, team leader, and mentor.
My primary expertise lies in JavaScript, PHP, and MySQL, although I am passionate about continuous learning and skill development. I embrace challenges as opportunities for growth and am always eager to acquire new knowledge and techniques.
I have been married since 2016 and became a father in 2020. I have been serving as an Engineering Manager at Dotdash Meredith since July 2022.
Qualifications
-
HTML5
95% -
CSS3
90% -
JS
75% -
PHP
75% -
DevOps
70% -
MySQL/MariaDB
70% -
Laravel
65% -
WordPress
60% -
React
60% -
VueJS
55% -
NodeJS
55% -
AngularJS
40% -
Gatsby
40% -
Java
25% -
Pyton
8%
Portfolio
Code Examples
MySQL Examples
SELECT JSON_QUERY(meta_value, '$.users') AS users FROM wp_postmeta WHERE meta_key = '_facility_meta'
SELECT post_id FROM wp_postmeta WHERE meta_key = '_facility_meta' AND JSON_CONTAINS(meta_value, 2, '$.users');
Shell Examples
for i in **/*.mp4; do eval $(ffprobe -v quiet -show_format -of flat=s=_ -show_entries stream=duration $i); echo $i,$streams_stream_0_duration >> ~/Downloads/videos.csv; done;
PHP Examples
class VideosController extends Controller
{
public function create(Request $request)
{
$page = ($request->page) ? (int) $request->page : 1;
$skip = ($page * 100) - 100;
return View::make('admin.videos', [
'pages' => ceil(count(Videos::whereNull('deleted_at')->get()) / 100),
'page' => $page,
'videos' => Videos::whereNull('deleted_at')->orderBy('path')->skip($skip)->take(100)->get(),
'ratings' => Ratings::all(),
'genres' => Genres::all()
]);
}
public function store(Request $request)
{
$names = $request->names;
$ratings = $request->ratings;
$lengths = $request->lengths;
$genres = $request->genres;
foreach($names as $id => $name) {
$arr = [];
$arr['name'] = $name;
if($lengths[$id]) $arr['length'] = $lengths[$id];
if($ratings[$id]) $arr['rating_id'] = $ratings[$id];
if($genres[$id]) $arr['genre_id'] = $genres[$id];
Videos::find($id)->update($arr);
}
return redirect(route('admin.videos') . '?page=' . $request->page);
}
}
JavaScript Examples
export default class Timer {
constructor(element, direction) {
this.element = element;
this.direction = direction;
this.init();
}
getTotalSeconds(startDate) {
let startDatetime = new Date(startDate);
let totalStartSeconds = startDatetime.getTime() / 1000;
let nowDatetime = new Date();
nowDatetime.setTime(nowDatetime.setTime(nowDatetime.getTime() + nowDatetime.getTimezoneOffset() * 60 * 1000));
let totalNowSeconds = new Date(nowDatetime.getTime() + -300 * 60 * 1000).getTime() / 1000;
return {
'startSeconds': totalStartSeconds,
'nowSeconds': totalNowSeconds
};
}
getTotalSecondsSince() {
let totalSecondsObj = this.getTotalSeconds(this.element.dataset.startDate);
let totalSeconds = totalSecondsObj.nowSeconds - totalSecondsObj.startSeconds;
return totalSeconds;
}
getTotalSecondsUntil() {
let totalSecondsObj = this.getTotalSeconds();
let totalSeconds = totalSecondsObj.startSeconds - totalSecondsObj.nowSeconds;
return totalSeconds;
}
convertDateToValues() {
let totalSeconds = 0;
if (this.direction == 'up') {
totalSeconds = this.getTotalSecondsSince();
} else {
totalSeconds = this.getTotalSecondsUntil();
}
let years, days, hours, minutes, seconds;
years = days = hours = minutes = seconds = 0;
if (totalSeconds >= 31536000) {
years = parseInt(totalSeconds / 31536000);
}
days = parseInt((totalSeconds - (years * 31536000)) / 86400);
hours = parseInt((totalSeconds - (days * 86400) - (years * 31536000)) / 3600);
minutes = parseInt((totalSeconds - (hours * 3600) - (days * 86400) - (years * 31536000)) / 60);
seconds = parseInt((totalSeconds - (minutes * 60) - (hours * 3600) - (days * 86400) - (years * 31536000)) % 60);
return {
'years': years,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds
};
};
setTimes() {
let values = this.convertDateToValues();
let yearsSpan = this.element.querySelector('.timer__years');
let daysSpan = this.element.querySelector('.timer__days');
let hoursSpan = this.element.querySelector('.timer__hours');
let minutesSpan = this.element.querySelector('.timer__minutes');
let secondsSpan = this.element.querySelector('.timer__seconds');
yearsSpan.innerHTML = values.years;
daysSpan.innerHTML = values.days;
hoursSpan.innerHTML = values.hours;
minutesSpan.innerHTML = values.minutes;
secondsSpan.innerHTML = values.seconds;
}
init() {
this.setTimes(this.element, this.direction)
setInterval(() => {
this.setTimes(this.element, this.direction);
}, 1000);
}
}
SCSS Examples
.about {
padding: 20px 0;
@media screen and (min-width: 1020px) {
padding: 32px 0;
}
&.media--left {
.about__media {
order: 1;
margin-bottom: 24px;
@media screen and (min-width: 1020px) {
margin-bottom: 0;
}
}
.about__notes {
order: 2;
}
}
&.media--right {
.about__media {
order: 2;
}
.about__notes {
order: 1;
margin-bottom: 24px;
@media screen and (min-width: 1020px) {
margin-bottom: 0;
}
}
}
&__notes {
p {
margin: 0 0 18px;
font-size: 18px;
line-height: 1.6;
letter-spacing: 1px;
word-spacing: 8px;
}
}
}
GraphQL Examples
{
strapiHomePage {
id
modules {
... on STRAPI__COMPONENT_MODULES_PORTFOLIO {
strapi_component
strapi_id
sectionTitle
portfolioItems {
title
slug
url
featuredImage {
alternativeText
caption
localFile {
childImageSharp {
gatsbyImageData(
width: 300
height: 300
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
transformOptions: {
cropFocus: CENTER
}
)
}
}
}
}
}
}
}
}