diff options
| -rw-r--r-- | dash/ads.php | 2 | ||||
| -rw-r--r-- | dash/apply.php | 4 | ||||
| -rw-r--r-- | dash/css/dash.css | 22 | ||||
| -rw-r--r-- | dash/css/employer.css | 12 | ||||
| -rw-r--r-- | dash/css/post.css | 65 | ||||
| -rw-r--r-- | dash/dash_employer.php | 4 | ||||
| -rw-r--r-- | dash/dash_functions.php | 17 | ||||
| -rw-r--r-- | dash/header.php | 4 | ||||
| -rw-r--r-- | dash/headless.php | 31 | ||||
| -rw-r--r-- | dash/img/1.png | bin | 0 -> 320 bytes | |||
| -rw-r--r-- | dash/img/check_blank.png | bin | 0 -> 2161 bytes | |||
| -rw-r--r-- | dash/img/check_hover.png | bin | 0 -> 2193 bytes | |||
| -rw-r--r-- | dash/img/star_empty.png | bin | 0 -> 2714 bytes | |||
| -rw-r--r-- | dash/img/star_given.png | bin | 0 -> 3792 bytes | |||
| -rw-r--r-- | dash/img/star_half.png | bin | 0 -> 3539 bytes | |||
| -rw-r--r-- | dash/img/unrated.png | bin | 0 -> 11010 bytes | |||
| -rw-r--r-- | dash/img/x_red.png | bin | 0 -> 2636 bytes | |||
| -rw-r--r-- | dash/js/dash.js | 40 | ||||
| -rw-r--r-- | dash/nav.php | 8 | ||||
| -rw-r--r-- | dash/post.php | 67 |
20 files changed, 250 insertions, 26 deletions
diff --git a/dash/ads.php b/dash/ads.php index 7187f86..46ebe25 100644 --- a/dash/ads.php +++ b/dash/ads.php @@ -6,7 +6,7 @@ $adid = intval($_GET['id']); if ($adid < 1) fatal('No ad ID has been provided. You must have reached this page in error.'); $title = 'Ad / Bulletin'; require('header.php'); -$result = $db->query('SELECT ads.id, ads.uid, ads.title, ads.pay, ads.time, ads.location, ads.description, users.name, users.email, users.phone, users.picture, users.bio, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads INNER JOIN users ON users.id = ads.uid LEFT JOIN ratings ON ratings.rated = ads.uid WHERE ads.id = '.$adid.' LIMIT 1') or dash_fatal($db->error); +$result = $db->query('SELECT ads.id, ads.uid, ads.title, ads.pay, ads.time, ads.location, ads.description, users.name, users.email, users.phone, users.picture, users.bio, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads INNER JOIN users ON users.id = ads.uid LEFT JOIN ratings ON ratings.rated = ads.uid WHERE ads.id = '.$adid.' GROUP BY ads.id LIMIT 1') or dash_fatal($db->error); if ($result->num_rows < 1) dash_fatal('No ad with this ID has been found.'); $row = $result->fetch_assoc(); $result->free(); diff --git a/dash/apply.php b/dash/apply.php index d60700e..82eb5f4 100644 --- a/dash/apply.php +++ b/dash/apply.php @@ -2,6 +2,8 @@ define('HEIRARCHY', 1); require('dash_common.php'); +if ($b_user['type'] != 'EMPLOYEE') fatal('Only job seeker accounts are allowed to apply to ads. Sorry for the inconvenience.'); + $adid = intval($_GET['id']); if ($adid < 1) fatal('No ad ID has been provided. You must have reached this page in error.'); $title = 'Apply / Bulletin'; @@ -18,7 +20,7 @@ if (!empty($_POST['apply'])) { dash_fatal('Your application has been submitted.', $b_config['base_url'].'dash/'); } -$result = $db->query('SELECT ads.id, ads.title, ads.pay, ads.time, ads.location, ads.description, users.name, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads INNER JOIN users ON users.id = ads.uid LEFT JOIN ratings ON ratings.rated = ads.uid WHERE ads.id = '.$adid.' LIMIT 1') or dash_fatal($db->error); +$result = $db->query('SELECT ads.id, ads.title, ads.pay, ads.time, ads.location, ads.description, users.name, users.picture, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads INNER JOIN users ON users.id = ads.uid LEFT JOIN ratings ON ratings.rated = ads.uid WHERE ads.id = '.$adid.' GROUP BY ads.id LIMIT 1') or dash_fatal($db->error); if ($result->num_rows < 1) dash_fatal('No ad with this ID has been found.'); $row = $result->fetch_assoc(); $result->free(); diff --git a/dash/css/dash.css b/dash/css/dash.css index b814fb0..29fb29f 100644 --- a/dash/css/dash.css +++ b/dash/css/dash.css @@ -54,8 +54,8 @@ body { font-weight: normal; text-decoration: none; color: #000000; - padding: 17px 0px; - margin: 0px 0.5em; + padding: 17px 0.5em; + margin: 0px; } #navlinks a:hover { color: #fb4d00; @@ -154,10 +154,14 @@ body { background-size: contain; background-repeat: no-repeat; } -.jobxbtn:hover, .appxbtn:hover { +.jobxbtn:hover { background-image: url('../img/x_hover.png'); cursor: pointer; } +.appxbtn:hover { + background-image: url('../img/x_red.png'); + cursor: pointer; +} #fulljob { margin: 2em auto 1em auto; position: absolute; @@ -335,3 +339,15 @@ h3 a:hover, h4 a:hover { .cbox .hr { width: 90%; } +.ratingdata { + display: block; + height: 16px; +} +.norating { + height: 16px; +} +.star { + width: 16px !important; + height: 16px !important; + margin: 0px 2px !important; +} diff --git a/dash/css/employer.css b/dash/css/employer.css index 95d6049..f2a1c37 100644 --- a/dash/css/employer.css +++ b/dash/css/employer.css @@ -15,3 +15,15 @@ color: #000000; margin-left: 10px; } +.appcbtn { + display: block; + width: 16px; + height: 16px; + float: left; + background-image: url('../img/check_blank.png'); + background-size: contain; + background-repeat: no-repeat; +} +.appcbtn:hover { + background-image: url('../img/check_hover.png'); +} diff --git a/dash/css/post.css b/dash/css/post.css new file mode 100644 index 0000000..378c439 --- /dev/null +++ b/dash/css/post.css @@ -0,0 +1,65 @@ +#postform input, #postform textarea, #postform select { + margin-top: 0.35em; + margin-bottom: 0.35em; + font-family: 'Myriad Pro'; + font-size: 12pt; +} +#postform p, #postform h3, #postform h4 { + margin: 0; +} +#postform input[type=text], #postform input[type=password], #postform input[type=number], #postform input[type=datetime-local] { + width: 248px; + padding: 6px 12px; + border: 1px solid #dddddd; + border-radius: 5px; +} +#postform input[type=number] { + width: 64px; +} +#postform input[type=submit], #postform input[type=button], #postform button { + background-color: #fb4d00; + padding: 5px 20px 3px; + border-style: none; + border-radius: 10px; + color: #ffffff; + cursor: pointer; +} +#postform input[type=submit]:hover, #postform input[type=button]:hover, #postform button:hover { + background-color: #fb7700; +} +#postform textarea { + margin: 0.25em auto; + width: 450px; + height: 150px; + resize: none; + border: 1px solid #dddddd; + border-radius: 5px; + padding: 5px; +} +#postform select { + padding: 5px; + background-color: #ffffff; + border-style: solid; + border-width: 1px; + border-color: #dddddd; + border-radius: 5px; + color: #000000; +} +#pfpt1 { + text-align: left; + padding: 0 2em; +} +#pfpt2 { + padding: 0 2em; +} +#pfpt2 input { + margin: 0.25em 5px; +} +#inptitle { + width: 90%; +} +#postform .err { + margin: 1em; + color: #a00000; + font-weight: bold; +} diff --git a/dash/dash_employer.php b/dash/dash_employer.php index 1dbdd16..d30ca04 100644 --- a/dash/dash_employer.php +++ b/dash/dash_employer.php @@ -22,12 +22,12 @@ $result->free(); </form> <?php if ($view == 0) { - $result = $db->query('SELECT ads.*, categories.cat_name, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads LEFT JOIN categories ON ads.cat = categories.id LEFT JOIN ratings ON ads.uid = ratings.rated WHERE ads.uid = '.$b_user['id'].' AND ads.closed = 0 GROUP BY ads.id LIMIT 0, '.$b_config['ads_per_page']) or fatal($db->error); + $result = $db->query('SELECT ads.*, categories.cat_name, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads LEFT JOIN categories ON ads.cat = categories.id LEFT JOIN ratings ON ads.uid = ratings.rated WHERE ads.uid = '.$b_user['id'].' AND ads.closed = 0 GROUP BY ads.id') or fatal($db->error); if ($result->num_rows < 1) draw_noads(); while ($row = $result->fetch_assoc()) draw_ad($row); $result->free(); } else { - $result = $db->query('SELECT responses.id, responses.comment, users.name, users.address, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM responses INNER JOIN users ON responses.uid = users.id LEFT JOIN ratings ON ratings.rated = responses.uid WHERE responses.adid = '.$view) or dash_fatal($db->error); + $result = $db->query('SELECT responses.id, responses.comment, responses.uid, users.name, users.address, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM responses INNER JOIN users ON responses.uid = users.id LEFT JOIN ratings ON ratings.rated = responses.uid WHERE responses.adid = '.$view.' AND responses.matched = 0 GROUP BY responses.id') or dash_fatal($db->error); if ($result->num_rows < 1) draw_noapps(); while ($row = $result->fetch_assoc()) draw_app($row); $result->free(); diff --git a/dash/dash_functions.php b/dash/dash_functions.php index cb22cd5..b12fdcd 100644 --- a/dash/dash_functions.php +++ b/dash/dash_functions.php @@ -17,8 +17,7 @@ function typestr ($type) { } } function rating_format ($rating = null, $typestr = 'Employer') { - if (is_null($rating)) return $typestr.' Not Rated'; - return number_format($rating, 1).' Star '.$typestr; + return '<span class="ratingdata" data-rating="'.(is_null($rating) ? 'undef' : number_format($rating, 1)).'"></span>'; } function draw_noads () { ?> @@ -57,14 +56,16 @@ function draw_ad ($row) { </div> <?php } + function draw_app ($row) { ?> <div class="job"> - <a href="#" class="appxbtn"></a> - <p class="jobtitle"><a href="review.php?id=<?=$row['id'];?>"><?=htmlentities($row['name']);?></a></p> + <a href="#" class="appxbtn" data-rid="<?=$row['id'];?>"></a> + <a href="#" class="appcbtn" data-rid="<?=$row['id'];?>"></a> + <p class="jobtitle"><a href="profile.php?id=<?=$row['uid'];?>"><?=htmlentities($row['name']);?></a></p> <p class="jobstars"><?=rating_format($row['rating'], 'Employee');?></p> - <p class="joblocation"><?=htmlentities($row['address']);?></p> - <p class="jobblurb"><?=htmlentities(substr($row['comment'], 0, min(strlen($row['comment']), 160)));?> <a href="review.php?id=<?=$row['id'];?>">[...]</a></p> + <p class="joblocation"><?=is_null($row['address']) ? '<em>No address listed.</em>' : htmlentities($row['address']);?></p> + <p class="jobblurb"><?=is_null($row['comment']) ? '<em>No comment included.</em>' : htmlentities($row['comment']);?></p> </p> </div> <?php @@ -93,4 +94,8 @@ function app_trigger ($responseid) { ); bulletin_mail($appinfo['email'], '"'.$appinfo['title'].'" Has Received a Response', tpl($options, 'app_eml.tpl')); } +function hire_trigger ($rid) { + global $db; + // TODO: this busywork +} ?> diff --git a/dash/header.php b/dash/header.php index 737d177..65de171 100644 --- a/dash/header.php +++ b/dash/header.php @@ -29,8 +29,10 @@ if (!empty($extra_head)) echo $extra_head; <?php foreach ($navtitles as $k => $title) { $link = $navlinks[$k]; + $test = '/'.$link; + $selected = ($_SERVER['SCRIPT_NAME'] == $test || $_SERVER['REQUEST_URI'] == $test); ?> - <a href="<?=htmlentities($b_config['base_url'].$link);?>"> + <a<?=$selected?' class="selected"':'';?> href="<?=htmlentities($b_config['base_url'].$link);?>"> <span class="navspan"><?=htmlentities($title);?></span> </a> <?php diff --git a/dash/headless.php b/dash/headless.php index ca090aa..d85a66a 100644 --- a/dash/headless.php +++ b/dash/headless.php @@ -1,13 +1,30 @@ <?php -$clicks = 0; -if (!empty($_GET['clicks'])) $clicks = max(0, intval($_GET['clicks'])); require('dash_common.php'); $db = new bdb(); -$result = $db->query('SELECT ads.*, categories.cat_name, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads LEFT JOIN categories ON ads.cat = categories.id LEFT JOIN ratings ON ads.uid = ratings.rated GROUP BY ads.id LIMIT '.($clicks+$b_config['ads_per_page']).', 1') or die(); -if ($result->num_rows) { - $row = $result->fetch_assoc(); - draw_ad($row); + +if (isset($_GET['clicks'])) { + $clicks = max(0, intval($_GET['clicks'])); + $result = $db->query('SELECT ads.*, categories.cat_name, SUM(ratings.stars) / COUNT(ratings.stars) AS rating FROM ads LEFT JOIN categories ON ads.cat = categories.id LEFT JOIN ratings ON ads.uid = ratings.rated GROUP BY ads.id LIMIT '.($clicks+$b_config['ads_per_page']).', 1') or die(); + if ($result->num_rows) { + $row = $result->fetch_assoc(); + draw_ad($row); + } + $result->free(); +} else if (isset($_GET['del'])) { + $result = $db->query('SELECT ads.uid FROM responses INNER JOIN ads ON ads.id = responses.adid WHERE responses.id = '.intval($_GET['del']).' LIMIT 1') or die('ERR'); + if ($result->num_rows < 1 || $result->fetch_assoc()['uid'] != $b_user['id']) die('PERM'); + $result->free(); + $db->query('DELETE FROM responses WHERE id = '.intval($_GET['del'])) or die('ERR'); + if ($db->affected_rows < 1) die('NOK'); + die('OK'); +} else if (isset($_GET['hire'])) { + $result = $db->query('SELECT ads.uid FROM responses INNER JOIN ads ON ads.id = responses.adid WHERE responses.id = '.intval($_GET['hire']).' LIMIT 1') or die('ERR'); + if ($result->num_rows < 1 || $result->fetch_assoc()['uid'] != $b_user['id']) die('PERM'); + $result->free(); + $db->query('UPDATE responses, ads SET responses.matched = 1, ads.closed = 1 WHERE ads.id = responses.adid AND responses.id = '.intval($_GET['hire'])) or die('ERR'); + if ($db->affected_rows < 1) die('NOK'); + hire_trigger(intval($_GET['hire']); + die('OK'); } -$result->free(); $db->close(); ?> diff --git a/dash/img/1.png b/dash/img/1.png Binary files differnew file mode 100644 index 0000000..c92417a --- /dev/null +++ b/dash/img/1.png diff --git a/dash/img/check_blank.png b/dash/img/check_blank.png Binary files differnew file mode 100644 index 0000000..a0de2d8 --- /dev/null +++ b/dash/img/check_blank.png diff --git a/dash/img/check_hover.png b/dash/img/check_hover.png Binary files differnew file mode 100644 index 0000000..b73c4eb --- /dev/null +++ b/dash/img/check_hover.png diff --git a/dash/img/star_empty.png b/dash/img/star_empty.png Binary files differnew file mode 100644 index 0000000..11cfffe --- /dev/null +++ b/dash/img/star_empty.png diff --git a/dash/img/star_given.png b/dash/img/star_given.png Binary files differnew file mode 100644 index 0000000..70cad61 --- /dev/null +++ b/dash/img/star_given.png diff --git a/dash/img/star_half.png b/dash/img/star_half.png Binary files differnew file mode 100644 index 0000000..c6de7ff --- /dev/null +++ b/dash/img/star_half.png diff --git a/dash/img/unrated.png b/dash/img/unrated.png Binary files differnew file mode 100644 index 0000000..89dd0ec --- /dev/null +++ b/dash/img/unrated.png diff --git a/dash/img/x_red.png b/dash/img/x_red.png Binary files differnew file mode 100644 index 0000000..b5999c2 --- /dev/null +++ b/dash/img/x_red.png diff --git a/dash/js/dash.js b/dash/js/dash.js index d3c1a1a..7fbceac 100644 --- a/dash/js/dash.js +++ b/dash/js/dash.js @@ -12,10 +12,48 @@ function jxbtn (e) { } function axbtn (e) { e.preventDefault(); - $(this).parents().filter('.job').hide(250); + if (window.confirm('Permanently remove this application?')) { + $(this).parents().filter('.job').hide(250); + $.get('headless.php?del='+$(this).attr('data-rid'), function (data) { + if (data != 'OK') window.alert('The application could not be permanently deleted. It has been removed from view for your convenience.'); + }); + } +} +function acbtn (e) { + e.preventDefault(); + if (window.confirm('Hire this candidate the job?')) { + $(this).parents().filter('.job').hide(250); + $.get('headless.php?hire='+$(this).attr('data-rid'), function (data) { + if (data == 'OK') { + window.alert('This application has been approved for hire. You can rate your experience with this candidate under the \'Rate\' tab.'); + window.location.href = '/dash/rate.php'; + } else { + window.alert('We\'ve experienced an error trying to approve this application. Please try again another time.'); + window.location.href = '/dash/'; + } + }); + } +} +function serveratings ($spaces) { + $.each($spaces, function (idx, me) { + var $me = $(me); + var rating = parseFloat($me.attr('data-rating')); + if (!rating && rating != 0) { + $me.html('<img class="norating" src="img/unrated.png" alt="Not Yet Rated" />'); + } else { + var html = ''; + for (var i = 1; i <= rating; i++) html += '<img class="star" src="img/star_given.png" alt="Full Star" />'; + if (rating-Math.floor(rating) >= 0.5) html += '<img class="star" src="img/star_half.png" alt="Half Star" />' + i += Math.round(rating-Math.floor(rating)); + for (; i <= 5; i++) html += '<img class="star" src="img/star_empty.png" alt="No Star" />'; + $me.html(html); + } + }); } $(function() { $('.jobxbtn').click(jxbtn); $('.appxbtn').click(axbtn); + $('.appcbtn').click(acbtn); + serveratings($('.ratingdata')); }); diff --git a/dash/nav.php b/dash/nav.php index 9baf7ad..bb01532 100644 --- a/dash/nav.php +++ b/dash/nav.php @@ -1,11 +1,11 @@ <?php if (!defined('ACC_TYPE')) die; if (ACC_TYPE == 'EMPLOYEE') { - $navtitles = array('Dashboard', 'Help'); - $navlinks = array('dash/', 'dash/help.php'); + $navtitles = array('Dashboard', 'Help', 'Rate'); + $navlinks = array('dash/', 'dash/help.php', 'dash/rate.php'); } else if (ACC_TYPE == 'EMPLOYER') { - $navtitles = array('Dashboard', 'Post an Ad', 'Help'); - $navlinks = array('dash/', 'dash/post.php', 'dash/help.php'); + $navtitles = array('Dashboard', 'Help', 'Rate', 'Post'); + $navlinks = array('dash/', 'dash/help.php', 'dash/rate.php', 'dash/post.php'); } else if (ACC_TYPE == 'ADMIN') { $navtitles = array(); $navlinks = array(); diff --git a/dash/post.php b/dash/post.php new file mode 100644 index 0000000..6fdd2fd --- /dev/null +++ b/dash/post.php @@ -0,0 +1,67 @@ +<?php +define('HEIRARCHY', 1); +require('dash_common.php'); +if ($b_user['type'] != 'EMPLOYER') fatal('Only job provider accounts are permitted to post ads.'); + +$title = 'Post an Ad / Bulletin'; +$extra_head = ' <link rel="stylesheet" type="text/css" href="css/post.css" />'; +require('header.php'); +do { + if (!empty($_POST['post'])) { + $patterns = array( + 'title' => '/^.+$/', + 'category' => '/^\d*$/', + 'description' => '/^.+$/', + 'pay' => '/^(\d+|\d+\.\d+|\.\d+)$/', + 'time' => '/^\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}$/', + 'location' => '/^.+$/', + ); + foreach ($patterns as $pkey => $pattern) { + if (!preg_match($pattern, $_POST[$pkey])) { + $err = 'One or more fields have been omitted. All fields are required in order to post an ad.'; + break; + } + } + $stmt = $db->prepare('INSERT INTO ads (uid, title, cat, pay, time, location, description) VALUES (?, ?, ?, ?, ?, ?, ?)') or dash_fatal($db->error); + $stmt->bind_param('isidiss', $b_user['id'], $_POST['title'], $_POST['cat'], $_POST['pay'], strtotime($_POST['time']), $_POST['location'], $_POST['description']); + $stmt->execute(); + if ($stmt->affected_rows < 1) dash_fatal('Your ad was unable to be posted.'); + dash_fatal('Your ad has been posted.', $b_config['base_url'].'dash/ads.php?id='.$stmt->insert_id); + } +} while (false); +$result = $db->query('SELECT id, cat_name FROM categories') or dash_fatal($db->error); +?> + <div class="box cbox"> + <h3><a href="/dash/post.php">Post an Ad</a></h3> + <div class="hr"></div> + <form id="postform" action="/dash/post.php" method="post"> + <div id="pfpt1"> + <p><input id="inptitle" type="text" name="title" placeholder="Title Your Ad" value="<?=htmlentities($_POST['title']);?>" /></p> + <p> + <select id="inpcat" name="category"> + <option value="0"<?=empty($_POST['category']) ? ' selected="selected"':'';?>>Uncategorized</option> +<?php +while ($row = $result->fetch_assoc()) + echo ' <option'.($row['id']==$_POST['category']?' selected="selected"':'').' value="'.$row['id'].'">'.htmlentities($row['cat_name']).'</option>'.PHP_EOL; +$result->free(); +?> + </select> + </p> + <p><textarea id="inpdesc" name="description" placeholder="Write a brief job description..."><?=htmlentities($_POST['description']);?></textarea></p> + </div> + <div class="hr"></div> + <div id="pfpt2"> + <p>Pays $<input id="inppay" type="number" name="pay" value="0.00" min="0" step="0.01" value="<?=htmlentities($_POST['pay']);?>" /></p> + <p>Takes place on... <input id="inptime" type="datetime-local" name="time" value="<?=htmlentities($_POST['time']);?>" /></p> + <p>At... <input id="inplocation" type="text" name="location" placeholder="1234 Main St" value="<?=htmlentities($_POST['location']);?>" /></p> + </div> +<?php +if (isset($err)) echo ' <div class="hr"></div>'.PHP_EOL.' <p class="err">'.htmlentities($err).'</p>'.PHP_EOL; +?> + <div class="hr"></div> + <p><input id="inppost" type="submit" name="post" value="Post Ad" /></p> + </form> + </div> +<?php +require('footer.php'); +?> |
