Moar jobs.

master
Nick Sergeant 2013-09-06 01:09:07 -04:00
parent 2b4ee8fc98
commit 15e94689fb
8 changed files with 194 additions and 107 deletions

View File

@ -5,31 +5,54 @@
{% block page-title %}Snipt Jobs{% endblock %}
{% block body-class %}{{ block.super }} static jobs{% endblock %}
{% block body-class %}{{ block.super }} static jobs search{% endblock %}
{% block js %}
window.jobs = [
{% for job in jobs %}
{{ job.data|safe }}{% if not forloop.last %},{% endif %}
{% endfor %}
];
{% endblock %}
{% block breadcrumb %}
<li><a href="/jobs/">Snipt Jobs</a></li>
{% endblock %}
{% block content %}
<section class="jobs">
<ul>
{% for job in jobs %}
<li>
<a href="{{ job.url }}?aff=dbe7e" class="group">
<div ng-controller="JobSearchController" ng-cloak class="ng-cloak">
<div class="static-box {% if page.object_list|length > 0 %}has-snipts{% endif %}">
<form method="get" class="form-search" action=".">
<input ng-model="query" type="text" class="search-query" name="q" placeholder="Filter jobs" />
</form>
</div>
<div class="pagination ng-cloak" ng-cloak ng-show="numberOfPages() > 1">
<button class="btn prev" style="margin: 0 10px;" href ng-disabled="currentPage == 0" ng-click="currentPage=currentPage - 1">Previous</button>
<span class="page">{[{ currentPage + 1 }]} / {[{ numberOfPages() }]}</span>
<button class="btn next" style="margin: 0 10px;" ng-disabled="currentPage >= jobs.length / pageSize - 1" ng-click="currentPage=currentPage + 1">Next</button>
</div>
<section class="jobs">
<ul>
<li ng-repeat="job in jobs|filter:query|startFrom:currentPage * pageSize|limitTo:pageSize">
<a href="{[{ job.url }]}?aff=dbe7e" class="group">
<span class="left">
<span class="job">{{ job.title }}</span>
<span class="company">{{ job.company }}</span>
<span class="job">{[{ job.title }]}</span>
<span class="company">{[{ job.company.name }]}</span>
</span>
<span class="right">
<span class="location">{{ job.location }}</span>
<span class="date">{{ job.created|naturalday }}</span>
<span class="location">{[{ job.company.location.city }]}</span>
<span class="date">{[{ job.created }]}</span>
</span>
</a>
</li>
{% endfor %}
</ul>
</section>
</ul>
</section>
<div class="pagination ng-cloak" ng-cloak ng-show="numberOfPages() > 1">
<button class="btn prev" style="margin: 0 10px;" href ng-disabled="currentPage == 0" ng-click="currentPage=currentPage - 1">Previous</button>
<span class="page">{[{ currentPage + 1 }]} / {[{ numberOfPages() }]}</span>
<button class="btn next" style="margin: 0 10px;" ng-disabled="currentPage >= jobs.length / pageSize - 1" ng-click="currentPage=currentPage + 1">Next</button>
</div>
</div>
{% endblock %}
{% block aside-top %}

View File

@ -1,9 +1,22 @@
from annoying.decorators import render_to
from annoying.decorators import ajax_request, render_to
from jobs.models import Job
import json
@render_to('jobs/jobs.html')
def jobs(request):
return {
'jobs': Job.objects.all().order_by('-created')
}
return {}
@ajax_request
def jobs_json(request):
jobs_json = []
jobs = Job.objects.all().order_by('-created')
for job in jobs:
jobs_json.append(json.loads(job.data))
return jobs_json

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1776,92 +1776,6 @@ body.is-pro {
}
}
}
body.jobs {
section.jobs {
margin: 30px;
h4 {
border-bottom: 1px solid #C0C0C0;
color: #999999;
font-size: 14px;
margin-top: 30px;
padding-bottom: 5px;
padding-left: 10px;
}
ul {
margin: 0;
li {
list-style-type: none;
margin: 10px 0;
a {
background: #FBFBFB;
border: 1px solid #DDDDDD;
color: #333333;
display: block;
padding: 10px;
@include border-radius;
@include box-shadow(0, 1px, 1px, rgba(0, 0, 0, .3));
&:hover {
background: rgba(#FBFBFB, .5);
}
span.left {
float: left;
span {
display: block;
&.job {
color: #3096B4;
font-size: 16px;
font-weight: bold;
margin-bottom: 4px;
}
}
}
span.right {
float: right;
span {
display: block;
text-align: right;
&.location {
color: #999999;
font-size: 16px;
font-weight: bold;
margin-bottom: 4px;
}
}
}
}
}
}
}
div.job-twitter {
margin-bottom: 15px;
margin-left: 15px;
}
div.post-job {
background: white;
border: 1px solid #DDDDDD;
margin-bottom: 30px;
margin-left: 15px;
padding: 15px;
@include border-radius;
p {
font-size: 12px;
margin-bottom: 0;
margin-top: 15px;
}
a {
width: 103px;
}
}
}
body.pro {
div.pro-hero {
background: transparent url('../img/pro-hero-bg.png') top left repeat;
@ -2698,3 +2612,99 @@ body.homepage {
}
}
body.jobs {
section.jobs {
margin: 30px;
h4 {
border-bottom: 1px solid #C0C0C0;
color: #999999;
font-size: 14px;
margin-top: 30px;
padding-bottom: 5px;
padding-left: 10px;
}
ul {
margin: 0;
li {
list-style-type: none;
margin: 10px 0;
a {
background: #FBFBFB;
border: 1px solid #DDDDDD;
color: #333333;
display: block;
padding: 10px;
@include border-radius;
@include box-shadow(0, 1px, 1px, rgba(0, 0, 0, .3));
&:hover {
background: rgba(#FBFBFB, .5);
}
span.left {
float: left;
span {
display: block;
&.job {
color: #3096B4;
font-size: 16px;
font-weight: bold;
margin-bottom: 4px;
}
}
}
span.right {
float: right;
span {
display: block;
text-align: right;
&.location {
color: #999999;
font-size: 16px;
font-weight: bold;
margin-bottom: 4px;
}
}
}
}
}
}
}
div.job-twitter {
margin-bottom: 15px;
margin-left: 15px;
text-align: center;
}
div.post-job {
background: white;
border: 1px solid #DDDDDD;
margin-bottom: 30px;
margin-left: 15px;
padding: 15px;
@include border-radius;
p {
font-size: 12px;
margin-bottom: 0;
margin-top: 15px;
}
a {
width: 103px;
}
}
div.static-box {
border: 1px solid #DDDDDD;
margin-left: 30px;
@include border-radius(50px);
form input.search-query {
width: 618px;
}
}
}

39
media/js/src/jobs.js Normal file
View File

@ -0,0 +1,39 @@
'use strict';
(function(window) {
if (typeof angular !== 'undefined') {
var root = window;
var $ = root.jQuery;
var controllers = {};
var app = root.app;
app.filter('startFrom', function() {
return function(input, start) {
start = +start;
return input.slice(start);
};
});
// Controllers.
controllers.JobSearchController = function($http, $scope) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$http.get('/jobs-json/').then(function(response) {
$scope.jobs = response.data;
});
$scope.numberOfPages = function() {
return Math.ceil($scope.jobs.length / $scope.pageSize);
};
};
// Assign the controllers.
app.controller(controllers);
}
})(window);

View File

@ -41,7 +41,7 @@
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/highlightjs-themes/tomorrow.css" />
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/blog-themes/default/style.css" />
{% else %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/snipt.css?92" />
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/snipt.css?93" />
{% endif %}
{% if has_snipts and not detail %}
@ -387,6 +387,7 @@
<script type="text/javascript" src="{{ STATIC_URL }}js/src/account.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/src/snipts.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/src/search.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}js/src/jobs.js"></script>
{% else %}
<script type="text/javascript" src="{{ STATIC_URL }}js/snipt-all.min.js?57"></script>
{% endif %}

View File

@ -11,7 +11,7 @@ from snipts.api import (PublicSniptResource, PublicTagResource,
from snipts.views import search
from tastypie.api import Api
from utils.views import SniptRegistrationView
from jobs.views import jobs
from jobs.views import jobs, jobs_json
from views import (homepage, lexers, login_redirect, pro_signup, sitemap, tags,
pro_signup_complete)
@ -48,6 +48,7 @@ urlpatterns = patterns('',
url(r'^sitemap.xml$', sitemap),
url(r'^tags/$', tags),
url(r'^jobs/$', jobs),
url(r'^jobs-json/$', jobs_json),
url(r'^pro/$', TemplateView.as_view(template_name='pro.html')),
url(r'^pro/signup/$', pro_signup),