Working on building out a proper account management page.
parent
28cfc79310
commit
6f34a45e35
|
@ -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 %}
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
{% 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 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 %}
|
||||
|
||||
{% block content %}
|
|
@ -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'),
|
||||
)
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1369,13 +1369,116 @@ div.site-notice {
|
|||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
body.detail {
|
||||
div.site-notice {
|
||||
margin-right: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
div.right-y {
|
||||
display: none;
|
||||
|
@ -1448,106 +1551,8 @@ body.detail {
|
|||
div.rochester-made {
|
||||
width: 840px;
|
||||
}
|
||||
}
|
||||
body.is-pro {
|
||||
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;
|
||||
}
|
||||
div.site-notice {
|
||||
margin-right: 100px;
|
||||
}
|
||||
}
|
||||
body.editing {
|
||||
|
@ -1707,133 +1712,80 @@ body.error {
|
|||
margin-top: 54px;
|
||||
}
|
||||
}
|
||||
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.api {
|
||||
body.is-pro {
|
||||
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;
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
aside.main {
|
||||
nav.footer {
|
||||
float: left;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
div#disqus_thread {
|
||||
width: 719px;
|
||||
}
|
||||
}
|
||||
body.blog {
|
||||
article.snipt {
|
||||
section.code {
|
||||
height: auto;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
div.alert {
|
||||
margin: 30px 30px 10px 30px;
|
||||
|
@ -1975,73 +2043,3 @@ body.tags {
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,37 +106,31 @@
|
|||
<li>
|
||||
<a href="/{{ request.user.username }}/">
|
||||
<i class="icon-user icon-white"></i>
|
||||
View profile
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.profile.is_pro %}
|
||||
<li>
|
||||
<a href="/stats/">
|
||||
<a href="/account/stats/">
|
||||
<i class="icon-star icon-white"></i>
|
||||
View stats
|
||||
Stats
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="/api/">
|
||||
<i class="icon-fire icon-white"></i>
|
||||
Get your API Key
|
||||
<a href="/account/">
|
||||
<i class="icon-cog icon-white"></i>
|
||||
Account
|
||||
</a>
|
||||
</li>
|
||||
{% if not request.user.profile.is_pro %}
|
||||
<li>
|
||||
<a href="/pro/">
|
||||
<i class="icon-star-empty icon-white"></i>
|
||||
Upgrade to Pro
|
||||
Go Pro
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li>
|
||||
<a href="/password/change/">
|
||||
<i class="icon-wrench icon-white"></i>
|
||||
Change password
|
||||
</a>
|
||||
</li>
|
||||
{% if request.user.is_superuser %}
|
||||
<li>
|
||||
<a href="/admin/">
|
||||
|
|
|
@ -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>
|
||||
<h6>Current Pro features:</h6>
|
||||
<ul>
|
||||
<li>No advertisements.</li>
|
||||
<li>Stats on "views" and "favorites" for your snipts.</li>
|
||||
<li>No ads.</li>
|
||||
<li>Statistics for "views" and "favorites" of your snipts.</li>
|
||||
<li>“Pro” 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>
|
||||
</ul>
|
||||
{% if request.user.profile.is_pro %}
|
||||
|
|
6
urls.py
6
urls.py
|
@ -1,5 +1,4 @@
|
|||
from views import (jobs, lexers, pro_signup,
|
||||
sitemap, tags, pro_signup_complete, stats)
|
||||
from views import (lexers, pro_signup, sitemap, tags, pro_signup_complete)
|
||||
from django.conf.urls.defaults import include, patterns, url
|
||||
from django.views.generic.simple import direct_to_template
|
||||
from utils.forms import SniptRegistrationForm
|
||||
|
@ -41,8 +40,7 @@ urlpatterns = patterns('',
|
|||
url(r'^pro/signup/$', pro_signup),
|
||||
url(r'^pro/signup/complete/$', pro_signup_complete),
|
||||
|
||||
#url(r'^jobs/$', jobs),
|
||||
url(r'^stats/$', stats),
|
||||
url(r'^account/', include('accounts.urls')),
|
||||
|
||||
url(r'^api/public/lexer/$', lexers),
|
||||
|
||||
|
|
21
views.py
21
views.py
|
@ -1,16 +1,12 @@
|
|||
from django.http import HttpResponseRedirect, HttpResponseBadRequest
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from annoying.decorators import ajax_request, render_to
|
||||
from django.template.defaultfilters import striptags
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from snipts.utils import get_lexers_list
|
||||
from django.db.models import Count
|
||||
from django.conf import settings
|
||||
from snipts.models import Snipt
|
||||
from taggit.models import Tag
|
||||
|
||||
import os, urllib
|
||||
|
||||
import stripe
|
||||
|
||||
|
@ -43,10 +39,6 @@ def lexers(request):
|
|||
|
||||
return {'objects': objects}
|
||||
|
||||
@render_to('jobs.html')
|
||||
def jobs(request):
|
||||
return {}
|
||||
|
||||
@login_required
|
||||
@render_to('pro-signup.html')
|
||||
def pro_signup(request):
|
||||
|
@ -92,19 +84,6 @@ def sitemap(request):
|
|||
context_instance=RequestContext(request),
|
||||
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')
|
||||
def tags(request):
|
||||
|
||||
|
|
Loading…
Reference in New Issue