Working on building out a proper account management page.

master
Nick Sergeant 2013-01-12 12:45:20 -05:00
parent 28cfc79310
commit 6f34a45e35
10 changed files with 359 additions and 335 deletions

0
accounts/forms.py Normal file
View File

View File

@ -0,0 +1,24 @@
{% extends "base.html" %}
{% block page-title %}/ Account - {{ block.super }}{% endblock %}
{% block body-class %}{{ block.super }} static account{% endblock %}
{% block breadcrumb %}
<li><a href="/account/">Account</a></li>
{% endblock %}
{% block content %}
<div class="static-box">
<h2>Account settings</h2>
<ul>
<li><a href="/api/">API</a> key: {{ request.user.api_key.key }}</li>
<li><a href="/api/">API</a> user ID: {{ request.user.id }}</li>
<li><a href="/password/change/">Change password</a></li>
{% if request.user.profile.is_pro %}
<li>Pro since: </li>
<li>GitTip username:</li>
{% endif %}
</ul>
</div>
{% endblock %}

View File

@ -2,12 +2,13 @@
{% load pagination_tags %} {% load pagination_tags %}
{% block page-title %}Stats {{ block.super }}{% endblock %} {% block page-title %}/ Stats / Account - {{ block.super }}{% endblock %}
{% block body-class %}{{ block.super }} static stats{% endblock %} {% block body-class %}{{ block.super }} static stats{% endblock %}
{% block breadcrumb %} {% block breadcrumb %}
<li><a href="/stats/">Stats</a></li> <li><a href="/account/">Account</a></li>
<span class="prompt">/</span> <li><a href="/account/stats/">Stats</a></li>
{% endblock %} {% endblock %}
{% block content %} {% block content %}

8
accounts/urls.py Normal file
View File

@ -0,0 +1,8 @@
from django.conf.urls.defaults import *
from accounts import views
urlpatterns = patterns('',
url(r'^$', views.account, name='account-detail'),
url(r'^stats/$', views.stats, name='account-stats'),
)

View File

@ -1 +1,22 @@
# Create your views here. from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from annoying.decorators import render_to
from snipts.models import Snipt
@login_required
@render_to('account.html')
def account(request):
return {}
@login_required
@render_to('stats.html')
def stats(request):
if not request.user.profile.is_pro:
return HttpResponseRedirect('/pro/')
snipts = Snipt.objects.filter(user=request.user).order_by('-views')
return {
'snipts': snipts
}

View File

@ -1369,13 +1369,116 @@ div.site-notice {
text-decoration: underline; text-decoration: underline;
} }
} }
body.detail {
div.site-notice {
margin-right: 100px;
}
}
// Pages // Pages
body.api {
section.main {
div.inner {
div.sifter {
margin-bottom: 0;
margin-top: 10px;
margin-right: 100px;
a.sifter-logo {
float: left;
img {
height: 30px;
margin: 0;
margin-top: 10px;
}
}
div.right {
float: left;
margin-left: 10px;
padding-top: 10px;
h3 {
margin: 0;
}
p {
margin: 0;
}
}
}
section.snipts {
article.snipt {
div.container {
header {
h1 {
a {
white-space: normal;
}
}
}
section.code {
height: auto;
}
}
}
}
}
aside.api-info {
float: right;
width: 190px;
div.api-inner {
background: rgba(#99D0DA, .3);
font: normal 11px $Helvetica;
margin: 0 0 30px 15px;
padding: 10px;
@include border-radius(8px);
h5 {
margin-bottom: 5px;
margin-top: 0;
}
ul {
margin: 0;
li {
margin: 2px 0;
list-style-type: none;
input {
margin-bottom: 0;
margin-top: 5px;
width: 145px;
}
}
}
}
&.api-creds {
div.api-inner {
margin-bottom: 0;
}
}
&.immediate-help {
margin-top: 20px;
p {
margin: 0;
}
}
}
aside.main {
nav.footer {
float: left;
margin-bottom: 0;
}
}
}
div#disqus_thread {
width: 719px;
}
}
body.blog {
article.snipt {
section.code {
height: auto;
}
}
}
body.detail { body.detail {
div.right-y { div.right-y {
display: none; display: none;
@ -1448,106 +1551,8 @@ body.detail {
div.rochester-made { div.rochester-made {
width: 840px; width: 840px;
} }
} div.site-notice {
body.is-pro { margin-right: 100px;
section.main {
div.inner {
section.snipts {
article.snipt {
margin-bottom: 0;
margin-top: 30px;
}
}
}
}
}
body.static {
.static-box {
background: rgba(#FFF, .65);
border: 1px solid #DDDDDD;
margin: 30px;
padding: 20px;
@include border-radius(4px);
div.form-actions {
margin-bottom: 0;
padding-bottom: 0;
@include vertical-gradient(#F5F5F5, #FBFBFB);
a.pull-right {
margin-left: 5px;
}
}
div.alert {
ul {
margin: 0;
li {
list-style-type: none;
}
}
}
div.alert-info {
a {
color: #3A87AD;
text-decoration: underline;
}
}
ul {
margin-bottom: 15px;
margin-top: 15px;
li {
font-size: 13px;
line-height: 18px;
margin: 5px 0;
}
}
h2 {
font-size: 24px;
line-height: 36px;
margin: 0;
}
h3 {
margin-bottom: 20px;
}
p {
line-height: 20px;
margin: 15px 0;
}
}
aside.main {
padding-top: 30px;
nav.footer {
margin-top: 10px;
}
}
div.alert-alone {
margin: 0;
}
form.form-horizontal {
legend + .control-group {
margin-top: 0;
}
div.form-actions {
margin-top: 27px;
}
fieldset {
padding-top: 27px;
legend {
margin: 0;
}
}
}
div#disqus_thread {
margin-left: 20px;
width: 709px;
div#dsq-content {
margin-top: 23px;
}
} }
} }
body.editing { body.editing {
@ -1707,133 +1712,80 @@ body.error {
margin-top: 54px; margin-top: 54px;
} }
} }
body.search { body.is-pro {
div.empty-snipts {
margin-top: 20px;
}
div.static-box {
border-left: 0;
margin-left: 0;
margin-right: 30px;
@include multi-border-radius(0px, 4px, 4px, 0px);
form {
margin-bottom: 0;
input.search-query {
width: 564px;
}
button {
padding: 4px 16px 4px;
}
}
}
}
body.api {
section.main { section.main {
div.inner { div.inner {
div.sifter {
margin-bottom: 0;
margin-top: 10px;
margin-right: 100px;
a.sifter-logo {
float: left;
img {
height: 30px;
margin: 0;
margin-top: 10px;
}
}
div.right {
float: left;
margin-left: 10px;
padding-top: 10px;
h3 {
margin: 0;
}
p {
margin: 0;
}
}
}
section.snipts { section.snipts {
article.snipt { article.snipt {
div.container {
header {
h1 {
a {
white-space: normal;
}
}
}
section.code {
height: auto;
}
}
}
}
}
aside.api-info {
float: right;
width: 190px;
div.api-inner {
background: rgba(#99D0DA, .3);
font: normal 11px $Helvetica;
margin: 0 0 30px 15px;
padding: 10px;
@include border-radius(8px);
h5 {
margin-bottom: 5px;
margin-top: 0;
}
ul {
margin: 0;
li {
margin: 2px 0;
list-style-type: none;
input {
margin-bottom: 0;
margin-top: 5px;
width: 145px;
}
}
}
}
&.api-creds {
div.api-inner {
margin-bottom: 0; margin-bottom: 0;
} margin-top: 30px;
}
&.immediate-help {
margin-top: 20px;
p {
margin: 0;
} }
} }
} }
aside.main {
nav.footer {
float: left;
margin-bottom: 0;
}
}
}
div#disqus_thread {
width: 719px;
} }
} }
body.blog { body.jobs {
article.snipt { section.jobs {
section.code { margin: 30px;
height: auto;
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;
}
}
}
}
}
} }
} }
} }
@ -1956,6 +1908,122 @@ body.pro {
} }
} }
} }
body.search {
div.empty-snipts {
margin-top: 20px;
}
div.static-box {
border-left: 0;
margin-left: 0;
margin-right: 30px;
@include multi-border-radius(0px, 4px, 4px, 0px);
form {
margin-bottom: 0;
input.search-query {
width: 564px;
}
button {
padding: 4px 16px 4px;
}
}
}
}
body.static {
.static-box {
background: rgba(#FFF, .65);
border: 1px solid #DDDDDD;
margin: 30px;
padding: 20px;
@include border-radius(4px);
div.form-actions {
margin-bottom: 0;
padding-bottom: 0;
@include vertical-gradient(#F5F5F5, #FBFBFB);
a.pull-right {
margin-left: 5px;
}
}
div.alert {
ul {
margin: 0;
li {
list-style-type: none;
}
}
}
div.alert-info {
a {
color: #3A87AD;
text-decoration: underline;
}
}
ul {
margin-bottom: 15px;
margin-top: 15px;
li {
font-size: 13px;
line-height: 18px;
margin: 5px 0;
}
}
h2 {
font-size: 24px;
line-height: 36px;
margin: 0;
}
h3 {
margin-bottom: 20px;
}
p {
line-height: 20px;
margin: 15px 0;
}
}
aside.main {
padding-top: 30px;
nav.footer {
margin-top: 10px;
}
}
div.alert-alone {
margin: 0;
}
form.form-horizontal {
legend + .control-group {
margin-top: 0;
}
div.form-actions {
margin-top: 27px;
}
fieldset {
padding-top: 27px;
legend {
margin: 0;
}
}
}
div#disqus_thread {
margin-left: 20px;
width: 709px;
div#dsq-content {
margin-top: 23px;
}
}
}
body.stats {
table {
margin-bottom: 0;
}
}
body.tags { body.tags {
div.alert { div.alert {
margin: 30px 30px 10px 30px; margin: 30px 30px 10px 30px;
@ -1975,73 +2043,3 @@ body.tags {
padding-top: 30px; padding-top: 30px;
} }
} }
body.stats {
table {
margin-bottom: 0;
}
}
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;
}
}
}
}
}
}
}
}

View File

@ -106,37 +106,31 @@
<li> <li>
<a href="/{{ request.user.username }}/"> <a href="/{{ request.user.username }}/">
<i class="icon-user icon-white"></i> <i class="icon-user icon-white"></i>
View profile Profile
</a> </a>
</li> </li>
{% if request.user.profile.is_pro %} {% if request.user.profile.is_pro %}
<li> <li>
<a href="/stats/"> <a href="/account/stats/">
<i class="icon-star icon-white"></i> <i class="icon-star icon-white"></i>
View stats Stats
</a> </a>
</li> </li>
{% endif %} {% endif %}
<li> <li>
<a href="/api/"> <a href="/account/">
<i class="icon-fire icon-white"></i> <i class="icon-cog icon-white"></i>
Get your API Key Account
</a> </a>
</li> </li>
{% if not request.user.profile.is_pro %} {% if not request.user.profile.is_pro %}
<li> <li>
<a href="/pro/"> <a href="/pro/">
<i class="icon-star-empty icon-white"></i> <i class="icon-star-empty icon-white"></i>
Upgrade to Pro Go Pro
</a> </a>
</li> </li>
{% endif %} {% endif %}
<li>
<a href="/password/change/">
<i class="icon-wrench icon-white"></i>
Change password
</a>
</li>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<li> <li>
<a href="/admin/"> <a href="/admin/">

View File

@ -14,9 +14,10 @@
<p>We're still building our <span class="pro">Pro</span> platform, but it already kicks ass. By becoming a Pro now, you'll also get access to future Pro features the moment they're released.</p> <p>We're still building our <span class="pro">Pro</span> platform, but it already kicks ass. By becoming a Pro now, you'll also get access to future Pro features the moment they're released.</p>
<h6>Current Pro features:</h6> <h6>Current Pro features:</h6>
<ul> <ul>
<li>No advertisements.</li> <li>No ads.</li>
<li>Stats on "views" and "favorites" for your snipts.</li> <li>Statistics for "views" and "favorites" of your snipts.</li>
<li>&ldquo;Pro&rdquo; badge throughout the site.</li> <li>&ldquo;Pro&rdquo; badge throughout the site.</li>
<li>GitTip</li>
<li>Custom domain for your <a href="https://blog.snipt.net/announcing-the-sniptnet-blogging-platform/">Snipt blog</a>. Contact <a href="mailto:support@snipt.net">support@snipt.net</a> to set it up.</li> <li>Custom domain for your <a href="https://blog.snipt.net/announcing-the-sniptnet-blogging-platform/">Snipt blog</a>. Contact <a href="mailto:support@snipt.net">support@snipt.net</a> to set it up.</li>
</ul> </ul>
{% if request.user.profile.is_pro %} {% if request.user.profile.is_pro %}

View File

@ -1,5 +1,4 @@
from views import (jobs, lexers, pro_signup, from views import (lexers, pro_signup, sitemap, tags, pro_signup_complete)
sitemap, tags, pro_signup_complete, stats)
from django.conf.urls.defaults import include, patterns, url from django.conf.urls.defaults import include, patterns, url
from django.views.generic.simple import direct_to_template from django.views.generic.simple import direct_to_template
from utils.forms import SniptRegistrationForm from utils.forms import SniptRegistrationForm
@ -41,8 +40,7 @@ urlpatterns = patterns('',
url(r'^pro/signup/$', pro_signup), url(r'^pro/signup/$', pro_signup),
url(r'^pro/signup/complete/$', pro_signup_complete), url(r'^pro/signup/complete/$', pro_signup_complete),
#url(r'^jobs/$', jobs), url(r'^account/', include('accounts.urls')),
url(r'^stats/$', stats),
url(r'^api/public/lexer/$', lexers), url(r'^api/public/lexer/$', lexers),

View File

@ -1,16 +1,12 @@
from django.http import HttpResponseRedirect, HttpResponseBadRequest from django.http import HttpResponseRedirect, HttpResponseBadRequest
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from annoying.decorators import ajax_request, render_to from annoying.decorators import ajax_request, render_to
from django.template.defaultfilters import striptags
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from snipts.utils import get_lexers_list from snipts.utils import get_lexers_list
from django.db.models import Count from django.db.models import Count
from django.conf import settings
from snipts.models import Snipt
from taggit.models import Tag from taggit.models import Tag
import os, urllib
import stripe import stripe
@ -43,10 +39,6 @@ def lexers(request):
return {'objects': objects} return {'objects': objects}
@render_to('jobs.html')
def jobs(request):
return {}
@login_required @login_required
@render_to('pro-signup.html') @render_to('pro-signup.html')
def pro_signup(request): def pro_signup(request):
@ -92,19 +84,6 @@ def sitemap(request):
context_instance=RequestContext(request), context_instance=RequestContext(request),
mimetype='application/xml') mimetype='application/xml')
@login_required
@render_to('stats.html')
def stats(request):
if not request.user.profile.is_pro:
return HttpResponseRedirect('/pro/')
snipts = Snipt.objects.filter(user=request.user).order_by('-views')
return {
'snipts': snipts
}
@render_to('tags.html') @render_to('tags.html')
def tags(request): def tags(request):