Merge branch 'master' into prod

This commit is contained in:
2018-10-21 10:42:47 -07:00
23 changed files with 618 additions and 443 deletions

View File

@@ -139,7 +139,7 @@ AUTH_PASSWORD_VALIDATORS = [
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ['SOCIAL_AUTH_GOOGLE_OAUTH2_KEY'] SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.environ['SOCIAL_AUTH_GOOGLE_OAUTH2_KEY']
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ['SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET'] SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.environ['SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET']
SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['andrew.cmu.edu', 'alumni.cmu.edu'] SOCIAL_AUTH_GOOGLE_OAUTH2_WHITELISTED_DOMAINS = ['andrew.cmu.edu', 'alumni.cmu.edu']
SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'hd': 'andrew.cmu.edu' } SOCIAL_AUTH_GOOGLE_OAUTH2_AUTH_EXTRA_ARGUMENTS = {'hd': '*' }
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/items/' SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/items/'
LOGIN_URL = '/login/google-oauth2/' LOGIN_URL = '/login/google-oauth2/'

View File

@@ -1,15 +1,61 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from __future__ import with_statement
from datetime import datetime, date
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.core.mail import send_mail from django.core.mail import send_mail
from django.template import loader from django.template import loader
from PIL import Image
from storages.backends.s3boto3 import S3Boto3Storage from storages.backends.s3boto3 import S3Boto3Storage
from stdimage.models import StdImageField from stdimage.models import StdImageField
from datetime import datetime, date from stdimage.utils import render_variations
from committee.models import Committee from committee.models import Committee
from django.db import models from django.db import models
#EXIF key index for the orientation value
ORIENTATION_KEY = 274
ROTATE_VALUES = {
3: Image.ROTATE_180,
6: Image.ROTATE_270,
8: Image.ROTATE_90,
}
# helper to fix "soft" rotated images
def resizeAndRotate(file_name, variations, storage):
rotated = False
with storage.open(file_name) as f:
try:
image = Image.open(f)
except:
return False
else:
with image:
try:
file_format = image.format
exif = image._getexif()
if exif and ORIENTATION_KEY in exif:
orientation = exif[ORIENTATION_KEY]
if orientation in ROTATE_VALUES:
image = image.transpose(ROTATE_VALUES[orientation])
rotated = True
if rotated:
with BytesIO() as file_buffer:
image.save(file_buffer, file_format)
f = ContentFile(file_buffer.getValue())
storage.delete(file_name)
storage.save(file_name, f)
except:
return True
render_variations(file_name, variations, storage=storage)
return False
class Item(models.Model): class Item(models.Model):
S3 = S3Boto3Storage() S3 = S3Boto3Storage()
@@ -25,6 +71,7 @@ class Item(models.Model):
(REJECTED, 'Rejected'), (REJECTED, 'Rejected'),
) )
desc = models.CharField(max_length=200) desc = models.CharField(max_length=200)
event = models.CharField(max_length=200) event = models.CharField(max_length=200)
committee = models.ForeignKey(Committee) committee = models.ForeignKey(Committee)
@@ -32,6 +79,7 @@ class Item(models.Model):
cost = models.DecimalField(max_digits=7, decimal_places=2) cost = models.DecimalField(max_digits=7, decimal_places=2)
date_purchased = models.DateField('date purchased') date_purchased = models.DateField('date purchased')
image = StdImageField(upload_to='images/%Y/%m/%d', image = StdImageField(upload_to='images/%Y/%m/%d',
render_variations=resizeAndRotate,
variations={'thumbnail': (600, 600)} variations={'thumbnail': (600, 600)}
) )
@@ -40,6 +88,7 @@ class Item(models.Model):
date_filed = models.DateTimeField('date filed') date_filed = models.DateTimeField('date filed')
status = models.CharField(max_length=2, choices=STATUS) status = models.CharField(max_length=2, choices=STATUS)
def approved(self): def approved(self):
return self.status == Item.PREAPPROVED return self.status == Item.PREAPPROVED

View File

@@ -1,18 +1,18 @@
appdirs==1.4.0 appdirs==1.4.0
boto3==1.4.4 boto3==1.9.28
botocore==1.5.7 botocore==1.12.28
Django==1.10.5 Django==1.11.16
django-cleanup==0.4.2 django-cleanup==0.4.2
django-stdimage==2.4.1 django-stdimage==2.4.1
django-storages==1.5.2 django-storages==1.5.2
docutils==0.13.1 docutils==0.13.1
futures==3.0.5 futures==3.0.5
gunicorn==19.6.0 gunicorn==19.9.0
jmespath==0.9.1 jmespath==0.9.1
oauthlib==2.0.1 oauthlib==2.1.0
olefile==0.44 olefile==0.44
packaging==16.8 packaging==16.8
Pillow==4.0.0 Pillow==5.3.0
progressbar2==3.12.0 progressbar2==3.12.0
psycopg2-binary==2.7.5 psycopg2-binary==2.7.5
PyJWT==1.4.2 PyJWT==1.4.2
@@ -20,10 +20,12 @@ pyparsing==2.1.10
python-dateutil==2.6.0 python-dateutil==2.6.0
python-openid==2.2.5 python-openid==2.2.5
python-utils==2.0.1 python-utils==2.0.1
pytz==2018.5
requests==2.13.0 requests==2.13.0
requests-oauthlib==0.7.0 requests-oauthlib==0.7.0
s3transfer==0.1.10 s3transfer==0.1.10
six==1.10.0 six==1.10.0
social-auth-app-django==1.0.1 social-auth-app-django==2.1.0
social-auth-core==1.1.0 social-auth-core==1.7.0
urllib3==1.23
whitenoise==3.3.0 whitenoise==3.3.0

4
sass/Makefile Normal file
View File

@@ -0,0 +1,4 @@
SRC=$(wildcard *.scss)
all: $(SRC)
sass include.scss ../static/css/site.css

View File

@@ -13,28 +13,30 @@
img { img {
border: 1px solid $midgray; border: 1px solid $midgray;
max-width: 100%; width: 100%;
} }
} }
.actions { .actions {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: $pad-m 0; margin: $pad-m 0;
a { a {
flex: 0 0 auto;
margin-bottom: $pad-m;
margin-right: $pad-m;
text-decoration: none; text-decoration: none;
font-size: 12px;
font-weight: normal;
} }
} }
.details { .details {
color: $text; border: 1px solid $midgray;
border-radius: $pad-s;
font-size: 12px; font-size: 12px;
font-weight: normal;
margin: $pad-m 0; margin: $pad-m 0;
padding: $pad-l; padding: $pad-l;
border-radius: $pad-s;
border: 1px solid $midgray;
span { span {
color: $midgray; color: $midgray;

105
sass/globals.scss Normal file
View File

@@ -0,0 +1,105 @@
$purple: #563d7c;
$gold: #fdd017;
$lightgray: #f8f8f8;
$midgray: #969499;
$darkgray: #4b4a4d;
$text: #252526;
$shadowgray: rgba(0, 0, 0, .8);
$lightshadowgray: rgba(0, 0, 0, 0.2);
// size constants
$pad-s: 2px;
$pad-m: 8px;
$pad-l: 16px;
$pad-xl: 36px;
html,
body {
background-color: $lightgray;
color: $text;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,sans-serif;
height: 100vh;
margin: 0;
padding: 0;
width: 100vw;
}
body {
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.nav {
align-items: center;
box-shadow: 0px 3px 12px $shadowgray;
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
flex: 0 0 auto;
height: 50px;
padding: $pad-l;
background-color: $purple;
color: $gold;
z-index: 10;
h3 {
font-weight: normal;
font-size: 16px;
margin: 0;
}
a {
color: $gold;
text-decoration: none;
font-size: 16px;
margin-left: $pad-m;
&:hover {
color: darken($gold, 20%);
text-decoration: initial;
}
}
}
.content {
align-items: center;
display: flex;
flex: 1 1 auto;
flex-direction: column;
position: relative;
overflow-y: auto;
min-height: 1;
}
.container {
background-color: #fff;
box-shadow: 0px 3px 12px $lightshadowgray;
display: flex;
flex: 0 0 auto;
flex-direction: column;
min-height: 1;
}
.btn {
background-color: #fff;
border-radius: $pad-s;
border: 1px solid $midgray;
box-sizing: border-box;
color: $purple;
cursor: pointer;
display: inline-block;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Helvetica,Arial,sans-serif;
font-size: 12px;
font-weight: normal;
padding: $pad-m $pad-l;
text-decoration: none;
vertical-align: middle;
white-space: nowrap;
&:hover {
background-color: lighten($purple, 35%);
}
}

View File

@@ -1,15 +1,17 @@
section { section {
color: $midgray; color: $midgray;
flex: 0 0 auto;
font-weight: lighter; font-weight: lighter;
font-size: 16px; font-size: 16px;
margin-top: 2*$pad-xl; margin-top: $pad-xl;
margin-bottom: -2*$pad-xl + $pad-l; text-align: center;
max-width: 960px;
margin-right: auto;
margin-left: auto;
} }
.items { .items {
display: flex;
flex-direction: column;
flex: 1 0 auto;
a.page { a.page {
display: inline-block; display: inline-block;
margin: $pad-m; margin: $pad-m;
@@ -30,13 +32,33 @@ section {
} }
} }
.pagination {
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: $pad-l;
padding: 0 $pad-xl;
width: 100%;
}
.item { .item {
display: flex;
flex-direction: column;
padding: $pad-m $pad-xl; padding: $pad-m $pad-xl;
margin: 0px; margin: 0px;
border-bottom: 1px solid $midgray; border-bottom: 1px solid $midgray;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
.committeeAndCost {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.committee { .committee {
color: $midgray; color: $midgray;
font-size: 12px; font-size: 12px;
@@ -49,10 +71,11 @@ section {
} }
.details-row { .details-row {
margin: $pad-m 0; color: $text;
font-size: 16px; font-size: 16px;
font-weight: lighter; font-weight: lighter;
color: $text; line-height: 24px;
margin: $pad-m 0;
padding: 0px; padding: 0px;
b { b {
@@ -103,17 +126,11 @@ section {
} }
} }
@media (min-width: 800px) { .emptyItems {
.item .cost { margin: $pad-xl;
float: right;
}
}
.empty {
margin: $pad-l;
color: $midgray; color: $midgray;
font-weight: lighter; font-size: 12px;
font-size: 16px; font-style: italic;
text-align: center; text-align: center;
} }
@@ -141,4 +158,9 @@ $button-size: 24px;
height: 36; height: 36;
font-size: 28; font-size: 28;
} }
&:hover {
background-color: darken($purple, 10%);
box-shadow: 0 0 12px rgba(0,0,0,.16),0 12px 12px rgba(0,0,0,.32);
}
} }

View File

@@ -14,17 +14,18 @@ body.login {
h3 { h3 {
font-size: 24px; font-size: 24px;
margin-bottom: $pad-m; margin-bottom: 0;
} }
h2 { h2 {
font-size: 28px; font-size: 28px;
margin-top: -$pad-l; margin: 0 auto;
} }
.btn { .btn {
background-color: $gold; background-color: $gold;
color: $purple; color: $purple;
font-size: 16px;
&:hover { &:hover {
background-color: darken($gold, 15%); background-color: darken($gold, 15%);

54
sass/new.scss Normal file
View File

@@ -0,0 +1,54 @@
h1 {
font-size: 18px;
font-weight: lighter;
color: $purple;
margin: $pad-l;
}
hr {
margin: $pad-l;
color: $midgray;
}
.inputRow {
box-sizing: border-box;
margin-bottom: $pad-l;
padding: 0 $pad-xl;
label {
color: $midgray;
font-weight: bold;
font-size: 12px;
margin-left: $pad-s;
}
input,
select,
textarea {
box-sizing: border-box;
border: 1px solid $midgray;
font-size: 16px;
line-height: 24px;
padding: $pad-s;
width: 100%;
}
textarea {
resize: vertical;
}
}
.editActions {
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 $pad-xl;
width: 100%;
}
.notes {
color: $midgray;
font-size: 12px;
margin: $pad-l $pad-xl;
}

View File

@@ -1,178 +1,254 @@
html,
body { body {
color: #252526;
font-family: sans-serif;
background-color: #f8f8f8; background-color: #f8f8f8;
padding-bottom: 0px; color: #252526;
margin: 0px 16px; } font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
height: 100vh;
margin: 0;
padding: 0;
width: 100vw;
}
body {
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.nav { .nav {
position: fixed; align-items: center;
top: 0; box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.8);
left: 0;
width: 100%;
height: 50px;
box-sizing: border-box; box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
flex: 0 0 auto;
height: 50px;
padding: 16px; padding: 16px;
background-color: #563d7c; background-color: #563d7c;
color: #fdd017; color: #fdd017;
box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.8); z-index: 10;
z-index: 10; } }
.nav h3 { .nav h3 {
font-weight: lighter; font-weight: normal;
font-size: 16px; font-size: 16px;
margin: 0; } margin: 0;
.nav a { }
float: right; .nav a {
color: #fdd017; color: #fdd017;
text-decoration: none; text-decoration: none;
font-size: 16px; font-size: 16px;
margin-left: 8px; } margin-left: 8px;
}
.nav a:hover {
color: #ad8b01;
text-decoration: initial;
}
.pull-right { .content {
float: right; align-items: center;
margin: 16px; } display: flex;
flex: 1 1 auto;
flex-direction: column;
position: relative;
overflow-y: auto;
min-height: 1;
}
.container { .container {
margin-bottom: 36; } background-color: #fff;
.container > div { box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.2);
margin-left: auto; display: flex;
margin-right: auto; flex: 0 0 auto;
margin-top: 64px; flex-direction: column;
max-width: 960; min-height: 1;
background-color: #fff; }
border: solid 1px #969499;
box-shadow: 0px 3px 9px rgba(51, 51, 51, 0.8); }
.btn { .btn {
background-color: #fff;
border-radius: 2px; border-radius: 2px;
border: 1px solid #969499; border: 1px solid #969499;
box-sizing: border-box;
color: #563d7c; color: #563d7c;
cursor: pointer;
display: inline-block; display: inline-block;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 12px;
font-weight: normal;
padding: 8px 16px; padding: 8px 16px;
text-decoration: none; text-decoration: none;
vertical-align: middle; vertical-align: middle;
white-space: nowrap; } white-space: nowrap;
.btn:hover { }
background-color: #b19dcf; } .btn:hover {
background-color: #b19dcf;
}
.approve { .approve {
padding: 36; } padding: 36px;
.approve .status { }
font-size: 16px; .approve .status {
color: #969499; font-size: 16px;
font-weight: lighter; } color: #969499;
.approve .status span { font-weight: lighter;
color: #252526; } }
.approve img { .approve .status span {
border: 1px solid #969499; color: #252526;
max-width: 100%; } }
.approve img {
border: 1px solid #969499;
width: 100%;
}
.actions { .actions {
margin: 8px 0; } display: flex;
.actions a { flex-direction: row;
text-decoration: none; flex-wrap: wrap;
font-size: 12px; margin: 8px 0;
font-weight: normal; } }
.actions a {
flex: 0 0 auto;
margin-bottom: 8px;
margin-right: 8px;
text-decoration: none;
}
.details { .details {
color: #252526; border: 1px solid #969499;
border-radius: 2px;
font-size: 12px; font-size: 12px;
font-weight: normal;
margin: 8px 0; margin: 8px 0;
padding: 16px; padding: 16px;
border-radius: 2px; }
border: 1px solid #969499; } .details span {
.details span { color: #969499;
color: #969499; } }
form.committee { form.committee {
border-bottom: 1px solid #969499; border-bottom: 1px solid #969499;
padding: 16px; padding: 16px;
margin-bottom: 0; } margin-bottom: 0;
}
section { section {
color: #969499; color: #969499;
flex: 0 0 auto;
font-weight: lighter; font-weight: lighter;
font-size: 16px; font-size: 16px;
margin-top: 72; margin-top: 36px;
margin-bottom: -56px; text-align: center;
max-width: 960px; }
margin-right: auto;
margin-left: auto; }
.items {
display: flex;
flex-direction: column;
flex: 1 0 auto;
}
.items a.page { .items a.page {
display: inline-block; display: inline-block;
margin: 8px; margin: 8px;
text-decoration: none; text-decoration: none;
color: #563d7c; color: #563d7c;
font-size: 12px; font-size: 12px;
float: right; } float: right;
}
.items a.page:hover { .items a.page:hover {
text-decoration: underline; } text-decoration: underline;
}
.items a.page.empty { .items a.page.empty {
color: #969499; color: #969499;
text-decoration: none; text-decoration: none;
cursor: default; } cursor: default;
}
.pagination {
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 16px;
padding: 0 36px;
width: 100%;
}
.item { .item {
padding: 8px 36; display: flex;
flex-direction: column;
padding: 8px 36px;
margin: 0px; margin: 0px;
border-bottom: 1px solid #969499; border-bottom: 1px solid #969499;
box-sizing: border-box; box-sizing: border-box;
width: 100%; } width: 100%;
.item .committee { }
color: #969499; .item .committeeAndCost {
font-size: 12px; align-items: center;
font-weight: bold; display: flex;
margin: 0px; } flex-direction: row;
.item a { justify-content: space-between;
text-decoration: none; } }
.item .details-row { .item .committee {
margin: 8px 0;
font-size: 16px;
font-weight: lighter;
color: #252526;
padding: 0px; }
.item .details-row b {
color: #4b4a4d; }
.item .details-row em {
color: #969499;
margin: 0 2px; }
.item .status {
color: #969499;
font-size: 12px;
margin: 0px; }
.item .cost {
display: inline-block;
text-align: center;
width: 120px;
height: 24px;
font-size: 12px;
color: #969499;
border-radius: 2px;
border: 1px solid #969499;
box-sizing: border-box;
padding: 4px;
margin: 4px 0; }
.item .approved {
background-color: #ffd9d9; }
.item .processed {
background-color: #d9ffd9; }
.item .rejected {
background-color: #969499;
color: #f8f8f8; }
.item .newItem {
background-color: #fff7d9; }
@media (min-width: 800px) {
.item .cost {
float: right; } }
.empty {
margin: 16px;
color: #969499; color: #969499;
font-weight: lighter; font-size: 12px;
font-weight: bold;
margin: 0px;
}
.item a {
text-decoration: none;
}
.item .details-row {
color: #252526;
font-size: 16px; font-size: 16px;
text-align: center; } font-weight: lighter;
line-height: 24px;
margin: 8px 0;
padding: 0px;
}
.item .details-row b {
color: #4b4a4d;
}
.item .details-row em {
color: #969499;
margin: 0 2px;
}
.item .status {
color: #969499;
font-size: 12px;
margin: 0px;
}
.item .cost {
display: inline-block;
text-align: center;
width: 120px;
height: 24px;
font-size: 12px;
color: #969499;
border-radius: 2px;
border: 1px solid #969499;
box-sizing: border-box;
padding: 4px;
margin: 4px 0;
}
.item .approved {
background-color: #ffd9d9;
}
.item .processed {
background-color: #d9ffd9;
}
.item .rejected {
background-color: #969499;
color: #f8f8f8;
}
.item .newItem {
background-color: #fff7d9;
}
.emptyItems {
margin: 36px;
color: #969499;
font-size: 12px;
font-style: italic;
text-align: center;
}
.btn-floating { .btn-floating {
position: fixed; position: fixed;
@@ -186,78 +262,98 @@ section {
z-index: 1000; z-index: 1000;
border-radius: 50%; border-radius: 50%;
text-align: center; text-align: center;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.16), 0 6px 12px rgba(0, 0, 0, 0.32); } box-shadow: 0 0 6px rgba(0, 0, 0, 0.16), 0 6px 12px rgba(0, 0, 0, 0.32);
.btn-floating span { }
display: block; .btn-floating span {
width: 36; display: block;
height: 36; width: 36;
font-size: 28; } height: 36;
font-size: 28;
}
.btn-floating:hover {
background-color: #3e2c5a;
box-shadow: 0 0 12px rgba(0, 0, 0, 0.16), 0 12px 12px rgba(0, 0, 0, 0.32);
}
body.login { body.login {
background-color: #563d7c; background-color: #563d7c;
color: #fdd017; } color: #fdd017;
}
.login { .login {
text-align: center; text-align: center;
color: #fdd017; } color: #fdd017;
.login div { }
margin-top: 30%; } .login div {
.login h3 { margin-top: 30%;
font-size: 24px; }
margin-bottom: 8px; } .login h3 {
.login h2 { font-size: 24px;
font-size: 28px; margin-bottom: 0;
margin-top: -16px; } }
.login .btn { .login h2 {
background-color: #fdd017; font-size: 28px;
color: #563d7c; } margin: 0 auto;
.login .btn:hover { }
background-color: #c69f02; } .login .btn {
background-color: #fdd017;
color: #563d7c;
font-size: 16px;
}
.login .btn:hover {
background-color: #c69f02;
}
h1 { h1 {
font-size: 18px; font-size: 18px;
font-weight: lighter; font-weight: lighter;
color: #563d7c; color: #563d7c;
margin: 16px; } margin: 16px;
}
hr { hr {
margin: 16px;
color: #969499; }
form div {
margin: 16px; }
form div * {
display: inline-block; }
form div label {
width: 180px;
color: #252526;
vertical-align: top; }
form div input, form div select, form div textarea {
width: 180px; }
form div.clear {
margin: -16px 0;
width: 180px; }
form div.clear:after {
content: "";
display: table;
clear: both; }
.rcol {
margin: 16px; margin: 16px;
color: #969499; color: #969499;
font-weight: lighter; } }
@media (min-width: 430px) { .inputRow {
form div { box-sizing: border-box;
width: 376px; } margin-bottom: 16px;
form div label { padding: 0 36px;
text-align: right; } }
form div input, form div select, form div textarea { .inputRow label {
width: 180px; color: #969499;
float: right; } } font-weight: bold;
@media (min-width: 800px) { font-size: 12px;
.rcol { margin-left: 2px;
float: right; }
width: 40%; } } .inputRow input,
.inputRow select,
.inputRow textarea {
box-sizing: border-box;
border: 1px solid #969499;
font-size: 16px;
line-height: 24px;
padding: 2px;
width: 100%;
}
.inputRow textarea {
resize: vertical;
}
.editActions {
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 36px;
width: 100%;
}
.notes {
color: #969499;
font-size: 12px;
margin: 16px 36px;
}
/*# sourceMappingURL=site.css.map */ /*# sourceMappingURL=site.css.map */

View File

@@ -1,4 +0,0 @@
SRC=$(wildcard *.scss)
all: $(SRC)
sass include.scss ../css/site.css

View File

@@ -1,86 +0,0 @@
$purple: #563d7c;
$gold: #fdd017;
$lightgray: #f8f8f8;
$midgray: #969499;
$darkgray: #4b4a4d;
$text: #252526;
$shadowgray: rgba(0, 0, 0, .8);
// size constants
$pad-s: 2px;
$pad-m: 8px;
$pad-l: 16px;
$pad-xl: 36;
body {
color: $text;
font-family: sans-serif;
background-color: $lightgray;
padding-bottom: 0px;
margin: 0px $pad-l;
}
.nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;;
box-sizing: border-box;
padding: 16px;
background-color: $purple;
color: $gold;
box-shadow: 0px 3px 12px $shadowgray;
z-index: 10;
h3 {
font-weight: lighter;
font-size: 16px;
margin: 0;
}
a {
float: right;
color: $gold;
text-decoration: none;
font-size: 16px;
margin-left: $pad-m;
}
}
.pull-right {
float: right;
margin: $pad-l;
}
.container {
margin-bottom: $pad-xl;
& > div {
margin-left: auto;
margin-right: auto;
margin-top: 64px;
max-width: 960;
background-color: #fff;
border: solid 1px $midgray;
box-shadow: 0px 3px 9px lighten($shadowgray, 20%);
}
}
.btn {
border-radius: $pad-s;
border: 1px solid $midgray;
color: $purple;
display: inline-block;
padding: $pad-m $pad-l;
text-decoration: none;
vertical-align: middle;
white-space: nowrap;
&:hover {
background-color: lighten($purple, 35%);
}
}

View File

@@ -1,74 +0,0 @@
h1 {
font-size: 18px;
font-weight: lighter;
color: $purple;
margin: $pad-l;
}
hr {
margin: $pad-l;
color: $midgray;
}
form {
div {
margin: $pad-l;
* {
display: inline-block;
}
label {
width: 180px;
color: $text;
vertical-align: top;
}
input, select, textarea {
width: 180px;
}
&.clear {
margin: -$pad-l 0;
width: 180px;
}
&.clear:after {
content: "";
display: table;
clear: both;
}
}
}
.rcol {
margin: $pad-l;
color: $midgray;
font-weight: lighter;
}
@media (min-width: 430px) {
form {
div {
width: 376px;
label {
text-align: right;
}
input, select, textarea {
width: 180px;
float: right;
}
}
}
}
@media (min-width: 800px) {
.rcol {
float: right;
width: 40%;
}
}

View File

@@ -9,15 +9,19 @@
</head> </head>
<body> <body>
<div class="nav"> <div class="nav">
<a href="/logout">logout</a>
{% if fincom %}
<a href="/committees">manage</a>
{% endif %}
<h3>The Aaron Gutierrez, '17, Fincom Web App</h3> <h3>The Aaron Gutierrez, '17, Fincom Web App</h3>
<div>
{% if fincom %}
<a href="/committees">manage</a>
{% endif %}
<a href="/logout">logout</a>
</div>
</div> </div>
<div class="container"> <div class="content">
{% block main %} <div class="container">
{% endblock %} {% block main %}
{% endblock %}
</div>
</div> </div>
{% block bottom %} {% block bottom %}
{% endblock %} {% endblock %}

View File

@@ -11,13 +11,13 @@
<div> <div>
<h3>Delta Beta Chapter</h3> <h3>Delta Beta Chapter</h3>
<h2>Fincom Webapp</h2> <h2>Fincom Webapp</h2>
{% if error %} <a class="btn btn-info"
<p>{{ error }}</p>
{% endif %}
<a class="btn btn-info btn-lg"
href="/login/google-oauth2/?next={{ next }}"> href="/login/google-oauth2/?next={{ next }}">
Login with your AndrewID Login with your AndrewID
</a> </a>
{% if error %}
<p>{{ error }}</p>
{% endif %}
</div> </div>
</body> </body>
</html> </html>

View File

@@ -8,7 +8,7 @@
<div class="approve"> <div class="approve">
{% if I.details %} {% if I.details %}
<div class="details"> <div class="details">
<span>Details:</span><br> <span>Details</span><br>
{{ I.details }}</div> {{ I.details }}</div>
{% endif %} {% endif %}
<div class="status">Status: <span>{{ I.statusText }}</span></div> <div class="status">Status: <span>{{ I.statusText }}</span></div>
@@ -23,7 +23,9 @@
<a href="/items" class="btn">Back</a> <a href="/items" class="btn">Back</a>
</div> </div>
<a href="{{ I.image.url }}"><img src="{{ I.image.thumbnail.url }}"></a> <a href="{{ I.image.url }}">
<img src="{{ I.image.thumbnail.url }}" alt="Click to view">
</a>
</div> </div>
</div> </div>

View File

@@ -5,25 +5,24 @@
{% block main %} {% block main %}
<div> <div>
<a href="/items" class="btn pull-right">Back</a>
<h1>Edit Reimbursements</h1> <h1>Edit Reimbursements</h1>
<hr> <hr>
<form action="/items/{{ I.pk }}/edit" method="post"> <form action="/items/{{ I.pk }}/edit" method="post">
{% csrf_token %} {% csrf_token %}
<div> <div class="inputRow">
<label for="desc">Item</label> <label for="desc">Item</label>
<input id="desc" type="text" name="desc" placeholder="What you bought" <input id="desc" type="text" name="desc" placeholder="What you bought"
value="{{ I.desc }}"> value="{{ I.desc }}">
</div> </div>
<div> <div class="inputRow">
<label for="event">Event</label> <label for="event">Event</label>
<input id="event" type="text" name="event" placeholder="When we need it" <input id="event" type="text" name="event" placeholder="When we need it"
value="{{ I.event }}"> value="{{ I.event }}">
</div> </div>
<div> <div class="inputRow">
<label for="committee">Committee or Budget</label> <label for="committee">Committee or Budget</label>
<select name="committee" id="committee"> <select name="committee" id="committee">
{% for C in committees %} {% for C in committees %}
@@ -36,29 +35,26 @@
</select> </select>
</div> </div>
<div> <div class="inputRow">
<label for="cost">Cost</label> <label for="cost">Cost</label>
<input id="cost" type="text" name="cost" placeholder="15.00" <input id="cost" type="text" name="cost" placeholder="15.00"
value="{{ I.cost }}"> value="{{ I.cost }}">
</div> </div>
<div> <div class="inputRow">
<label for="date">Date Purchased</label> <label for="date">Date Purchased</label>
<input id="date" type="date" name="date" placeholder="mm/dd/yyyy" <input id="date" type="date" name="date" placeholder="mm/dd/yyyy"
value="{{ I.date_purchased }}"> value="{{ I.date_purchased }}">
</div> </div>
<div class="clear"> <div class="inputRow">
<div>
<label for="details">Details</label> <label for="details">Details</label>
<textarea id="details" name="details" rows="4" class="clear">{{ I.details }}</textarea> <textarea id="details" name="details" rows="4">{{ I.details }}</textarea>
</div>
</div> </div>
<div class="clear"> <div class="editActions">
<div> <a href="/items" class="btn">Back</a>
<input type="submit"> <input type="submit" class="btn">
</div>
</div> </div>
</form> </form>
</div> </div>

View File

@@ -30,7 +30,7 @@ Please review and then approve or reject the request from {{ submitter }} for {{
</a> </a>
<div style="color: #969499; font-size: 12px; margin: 0px;"> <div style="color: #969499; font-size: 12px; margin: 0px;">
{% if I.approved or I.processed %} {% if I.approved or I.processed %}
Approved By: Approved By:
{% for u in I.approved_by.all %} {% for u in I.approved_by.all %}
{{ u.first_name }} {{ u.last_name }} {{ u.first_name }} {{ u.last_name }}
{% endfor %} {% endfor %}

View File

@@ -1,18 +1,20 @@
<div class="item"> <div class="item">
<div class="committee"> <div class="committeeAndCost">
{{ I.comName }} <div class="committee">
</div> {{ I.comName }}
{% if I.approved %}
<div class="cost approved">
{% elif I.processed %}
<div class="cost processed">
{% elif I.rejected %}
<div class="cost rejected">
{% else %}
<div class="cost newItem">
{% endif %}
${{ I.cost|floatformat:"2" }}
</div> </div>
{% if I.approved %}
<div class="cost approved">
{% elif I.processed %}
<div class="cost processed">
{% elif I.rejected %}
<div class="cost rejected">
{% else %}
<div class="cost newItem">
{% endif %}
${{ I.cost|floatformat:"2" }}
</div>
</div>
<a href="/items/{{ I.pk }}"> <a href="/items/{{ I.pk }}">
<div class="details-row"> <div class="details-row">
<b>{{ I.event }}:</b> <b>{{ I.event }}:</b>

View File

@@ -5,27 +5,23 @@
{% block main %} {% block main %}
<div> <div>
<h1>Add New Reimbursements</h1> <h1>New Reimbursement</h1>
<hr> <hr>
<div class="rcol">
Make sure all information is accurate, you submit an itemized receipt, and
you select the correct committee.
</div>
<form action="/items/new" method="post" enctype="multipart/form-data"> <form action="/items/new" method="post" enctype="multipart/form-data">
{% csrf_token %} {% csrf_token %}
<div> <div class="inputRow">
<label for="desc">Item</label> <label for="desc">Item</label>
<input id="desc" type="text" name="desc" placeholder="What you bought"> <input id="desc" type="text" name="desc" placeholder="What you bought">
</div> </div>
<div> <div class="inputRow">
<label for="event">Event</label> <label for="event">Event</label>
<input id="event" type="text" name="event" placeholder="When we need it"> <input id="event" type="text" name="event" placeholder="When we need it">
</div> </div>
<div> <div class="inputRow">
<label for="committee">Committee or Budget</label> <label for="committee">Committee or Budget</label>
<select name="committee" id="committee"> <select name="committee" id="committee">
<option disabled selected>Select a committee</option> <option disabled selected>Select a committee</option>
@@ -35,32 +31,34 @@
</select> </select>
</div> </div>
<div> <div class="inputRow">
<label for="cost">Cost</label> <label for="cost">Cost</label>
<input id="cost" type="text" name="cost" placeholder="15.00"> <input id="cost" type="text" name="cost" placeholder="15.00">
</div> </div>
<div> <div class="inputRow">
<label for="date">Date Purchased</label> <label for="date">Date Purchased</label>
<input id="date" type="date" name="date" placeholder="mm/dd/yyyy"> <input id="date" type="date" name="date" placeholder="mm/dd/yyyy">
</div> </div>
<div class="clear"> <div class="inputRow">
<div>
<label for="details">Details</label> <label for="details">Details</label>
<textarea id="details" name="details" rows="4" class="clear"></textarea> <textarea id="details" name="details" rows="4"></textarea>
</div>
</div> </div>
<div> <div class="inputRow">
<label for="image">Receipt</label> <label for="image">Receipt</label>
<input type="file" name="image" id="image" accept="image/*"> <input type="file" name="image" id="image" accept="image/*">
</div> </div>
<div class="clear"> <div class="notes">
<div> Make sure all information is accurate, you submit an itemized receipt, and
<input type="submit"> you select the correct committee.
</div> </div>
<div class="editActions">
<a href="/items" class="btn">Back</a>
<input type="submit" class="btn">
</div> </div>
</form> </form>
</div> </div>

View File

@@ -3,15 +3,9 @@
{% for I in items %} {% for I in items %}
{% include "./item.html" %} {% include "./item.html" %}
{% empty %} {% empty %}
<div class="empty">No Reimbursements</div> <div class="emptyItems">No Reimbursements</div>
{% endfor %} {% endfor %}
{% if items.has_next %} <div class="pagination">
<a class="page" href="?{{ pagination_key }}={{ items.next_page_number }}">
Older &rarr;
</a>
{% else %}
<a class="page empty">Older &rarr;</a>
{% endif %}
{% if items.has_previous %} {% if items.has_previous %}
<a class="page" href="?{{ pagination_key }}={{ items.previous_page_number }}"> <a class="page" href="?{{ pagination_key }}={{ items.previous_page_number }}">
&larr; Newer &larr; Newer
@@ -19,4 +13,12 @@
{% else %} {% else %}
<a class="page empty">&larr; Newer</a> <a class="page empty">&larr; Newer</a>
{% endif %} {% endif %}
{% if items.has_next %}
<a class="page" href="?{{ pagination_key }}={{ items.next_page_number }}">
Older &rarr;
</a>
{% else %}
<a class="page empty">Older &rarr;</a>
{% endif %}
</div>
</div> </div>