Merge branch 'master' into prod

This commit is contained in:
Aaron Gutierrez
2019-01-27 18:53:43 +00:00
32 changed files with 675 additions and 493 deletions

View File

@@ -1,5 +1,6 @@
from django.contrib import admin
from models import Committee
from committee.models import Committee
# Register your models here.
admin.site.register(Committee)

View File

@@ -5,7 +5,7 @@ from django.db import models
class Committee(models.Model):
name = models.CharField(max_length=100, unique=True)
chair = models.ForeignKey(User, null=True)
chair = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.name

View File

@@ -1,10 +1,11 @@
from django.conf.urls import url
from . import views
from django.urls import path
from committee import views
urlpatterns = [
url(r'^$', views.edit, name='edit'),
url(r'^update/(?P<committee>\d+)/$', views.update, name='update'),
url(r'^fincom/$', views.add_to_fincom, name='add_to_fincom'),
url(r'^fincom/delete$', views.remove_fincom, name='remove_fincom'),
url(r'^new$', views.new_committee, name='new_committee'),
path('', views.edit, name='edit'),
path('update/<int:committee>/', views.update, name='update'),
path('fincom/', views.add_to_fincom, name='add_to_fincom'),
path('fincom/delete', views.remove_fincom, name='remove_fincom'),
path('new', views.new_committee, name='new_committee'),
]

View File

@@ -2,7 +2,8 @@ from django.shortcuts import HttpResponse, HttpResponseRedirect
from django.template import loader
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User, Group
from models import Committee
from committee.models import Committee
@login_required
def edit(request):
@@ -68,4 +69,4 @@ def remove_fincom(request):
user.groups.remove(Group.objects.filter(name='Fincom')[0])
user.save()
return HttpResponseRedirect('/committees')
return HttpResponseRedirect('/committees')

View File

@@ -28,7 +28,7 @@ DEBUG = False
ALLOWED_HOSTS = [
'localhost',
'dtd-fincom.herokuapp.com',
'fincom.frat.tech',
'fincom.delt.space',
]
@@ -98,10 +98,10 @@ WSGI_APPLICATION = 'fincom.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'dbu9ujb6cnhc3n',
'USER': 'dexgqmkgoabqyd',
'PASSWORD': os.environ['DBPASSWD'],
'HOST': 'ec2-50-19-89-124.compute-1.amazonaws.com',
'NAME': 'fincom',
'USER': 'fincom',
'PASSWORD': 'fincom',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
@@ -110,8 +110,8 @@ DATABASES = {
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID=os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY=os.environ['AWS_SECRET_ACCESS_KEY']
AWS_AUTO_CREATE_BUCKET=True
AWS_STORAGE_BUCKET_NAME='fincom'
AWS_DEFAULT_ACL=None
AWS_S3_FILE_OVERWRITE=False
@@ -139,7 +139,7 @@ AUTH_PASSWORD_VALIDATORS = [
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_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/'
LOGIN_URL = '/login/google-oauth2/'

View File

@@ -13,16 +13,16 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include, url
from django.urls import include, path
from django.contrib import admin
from . import views
from fincom import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^logout$', views.user_logout, name='logout'),
url(r'^items/', include('items.urls')),
url(r'^committees/', include('committee.urls')),
url('.well-known/acme-challenge/tVQ35BIrm7ybiASBxRMHG2CAO44x-I2BVMqcrv_yJ2k', views.encrypt, name='encrypt'),
url('', include('social_django.urls', namespace='social')),
url(r'^admin/', admin.site.urls),
path('', views.index, name='index'),
path('logout', views.user_logout, name='logout'),
path('items/', include('items.urls')),
path('committees/', include('committee.urls')),
path('', include('social_django.urls', namespace='social')),
path('admin/', admin.site.urls),
]

View File

@@ -3,15 +3,12 @@ from django.contrib.auth import logout
from django.template import loader
def index(request):
if request.user.is_authenticated():
if request.user.is_authenticated:
return HttpResponseRedirect('/items')
template = loader.get_template('fincom/index.html')
return HttpResponse(template.render({}, request))
def encrypt(request):
return HttpResponse('tVQ35BIrm7ybiASBxRMHG2CAO44x-I2BVMqcrv_yJ2k.g4Ct3egntTJZl1LOzJH8v9Ri24BQ7blYjcbzPucJVE4', request)
def user_logout(request):
logout(request)

View File

@@ -1,5 +1,5 @@
from django.contrib import admin
from models import Item
from items.models import Item
# Register your models here.
admin.site.register(Item)

View File

@@ -1,15 +1,62 @@
from __future__ import unicode_literals
from __future__ import with_statement
from datetime import datetime, date
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
from django.core.mail import send_mail
from django.template import loader
from io import BytesIO
from PIL import Image
from storages.backends.s3boto3 import S3Boto3Storage
from stdimage.models import StdImageField
from datetime import datetime, date
from stdimage.utils import render_variations
from committee.models import Committee
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):
S3 = S3Boto3Storage()
@@ -25,21 +72,24 @@ class Item(models.Model):
(REJECTED, 'Rejected'),
)
desc = models.CharField(max_length=200)
event = models.CharField(max_length=200)
committee = models.ForeignKey(Committee)
committee = models.ForeignKey(Committee, on_delete=models.DO_NOTHING)
details = models.TextField()
cost = models.DecimalField(max_digits=7, decimal_places=2)
date_purchased = models.DateField('date purchased')
image = StdImageField(upload_to='images/%Y/%m/%d',
render_variations=resizeAndRotate,
variations={'thumbnail': (600, 600)}
)
created_by = models.ForeignKey(User, related_name='created_by')
created_by = models.ForeignKey(User, related_name='created_by', on_delete=models.DO_NOTHING)
approved_by = models.ManyToManyField(User, blank=True, related_name='approved_by')
date_filed = models.DateTimeField('date filed')
status = models.CharField(max_length=2, choices=STATUS)
def approved(self):
return self.status == Item.PREAPPROVED

View File

@@ -1,12 +1,12 @@
from django.conf.urls import url
from . import views
from django.urls import path
from items import views
urlpatterns = [
url(r'^$', views.list, name='list'),
url(r'^(?P<item_id>\d+)/$', views.details, name='details'),
url(r'^(?P<item_id>\d+)/approve$', views.approve, name='approve'),
url(r'^(?P<item_id>\d+)/reject$', views.reject, name='reject'),
url(r'^(?P<item_id>\d+)/edit$', views.edit, name='edit'),
url(r'^(?P<item_id>\d+)/delete$', views.delete, name='delete'),
url(r'^new$', views.new_form, name='new_form'),
path(r'', views.list, name='list'),
path('<int:item_id>/', views.details, name='details'),
path('<int:item_id>/approve', views.approve, name='approve'),
path('<int:item_id>/reject', views.reject, name='reject'),
path('<int:item_id>/edit', views.edit, name='edit'),
path('<int:item_id>/delete', views.delete, name='delete'),
path('new', views.new_form, name='new_form'),
]

View File

@@ -4,8 +4,9 @@ from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from models import Item
from committee.models import Committee
from items.models import Item
def isAuthorised(request, item):
return (request.user == item.committee.chair

View File

@@ -1,29 +1,36 @@
appdirs==1.4.0
boto3==1.4.4
botocore==1.5.7
Django==1.10.5
boto3==1.9.86
botocore==1.12.86
certifi==2018.11.29
chardet==3.0.4
defusedxml==0.5.0
Django==2.1.5
django-cleanup==0.4.2
django-stdimage==2.4.1
django-storages==1.5.2
docutils==0.13.1
docutils==0.14
futures==3.0.5
gunicorn==19.6.0
jmespath==0.9.1
oauthlib==2.0.1
idna==2.8
jmespath==0.9.3
oauthlib==3.0.1
olefile==0.44
packaging==16.8
Pillow==4.0.0
pkg-resources==0.0.0
progressbar2==3.12.0
psycopg2-binary==2.7.5
PyJWT==1.4.2
PyJWT==1.7.1
pyparsing==2.1.10
python-dateutil==2.6.0
python-dateutil==2.7.5
python-openid==2.2.5
python-utils==2.0.1
requests==2.13.0
requests-oauthlib==0.7.0
s3transfer==0.1.10
six==1.10.0
social-auth-app-django==1.0.1
social-auth-core==1.1.0
python3-openid==3.1.0
pytz==2018.9
requests==2.21.0
requests-oauthlib==1.2.0
s3transfer==0.1.13
six==1.12.0
social-auth-app-django==3.1.0
social-auth-core==3.0.0
urllib3==1.24.1
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 {
border: 1px solid $midgray;
max-width: 100%;
width: 100%;
}
}
.actions {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: $pad-m 0;
a {
flex: 0 0 auto;
margin-bottom: $pad-m;
margin-right: $pad-m;
text-decoration: none;
font-size: 12px;
font-weight: normal;
}
}
.details {
color: $text;
border: 1px solid $midgray;
border-radius: $pad-s;
font-size: 12px;
font-weight: normal;
margin: $pad-m 0;
padding: $pad-l;
border-radius: $pad-s;
border: 1px solid $midgray;
span {
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 {
color: $midgray;
flex: 0 0 auto;
font-weight: lighter;
font-size: 16px;
margin-top: 2*$pad-xl;
margin-bottom: -2*$pad-xl + $pad-l;
max-width: 960px;
margin-right: auto;
margin-left: auto;
margin-top: $pad-xl;
text-align: center;
}
.items {
display: flex;
flex-direction: column;
flex: 1 0 auto;
a.page {
display: inline-block;
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 {
display: flex;
flex-direction: column;
padding: $pad-m $pad-xl;
margin: 0px;
border-bottom: 1px solid $midgray;
box-sizing: border-box;
width: 100%;
.committeeAndCost {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.committee {
color: $midgray;
font-size: 12px;
@@ -49,10 +71,11 @@ section {
}
.details-row {
margin: $pad-m 0;
color: $text;
font-size: 16px;
font-weight: lighter;
color: $text;
line-height: 24px;
margin: $pad-m 0;
padding: 0px;
b {
@@ -103,17 +126,11 @@ section {
}
}
@media (min-width: 800px) {
.item .cost {
float: right;
}
}
.empty {
margin: $pad-l;
.emptyItems {
margin: $pad-xl;
color: $midgray;
font-weight: lighter;
font-size: 16px;
font-size: 12px;
font-style: italic;
text-align: center;
}
@@ -141,4 +158,9 @@ $button-size: 24px;
height: 36;
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 {
font-size: 24px;
margin-bottom: $pad-m;
margin-bottom: 0;
}
h2 {
font-size: 28px;
margin-top: -$pad-l;
margin: 0 auto;
}
.btn {
background-color: $gold;
color: $purple;
font-size: 16px;
&:hover {
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 {
color: #252526;
font-family: sans-serif;
background-color: #f8f8f8;
padding-bottom: 0px;
margin: 0px 16px; }
color: #252526;
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 {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 50px;
align-items: center;
box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.8);
box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
flex: 0 0 auto;
height: 50px;
padding: 16px;
background-color: #563d7c;
color: #fdd017;
box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.8);
z-index: 10; }
.nav h3 {
font-weight: lighter;
font-size: 16px;
margin: 0; }
.nav a {
float: right;
color: #fdd017;
text-decoration: none;
font-size: 16px;
margin-left: 8px; }
z-index: 10;
}
.nav h3 {
font-weight: normal;
font-size: 16px;
margin: 0;
}
.nav a {
color: #fdd017;
text-decoration: none;
font-size: 16px;
margin-left: 8px;
}
.nav a:hover {
color: #ad8b01;
text-decoration: initial;
}
.pull-right {
float: right;
margin: 16px; }
.content {
align-items: center;
display: flex;
flex: 1 1 auto;
flex-direction: column;
position: relative;
overflow-y: auto;
min-height: 1;
}
.container {
margin-bottom: 36; }
.container > div {
margin-left: auto;
margin-right: auto;
margin-top: 64px;
max-width: 960;
background-color: #fff;
border: solid 1px #969499;
box-shadow: 0px 3px 9px rgba(51, 51, 51, 0.8); }
background-color: #fff;
box-shadow: 0px 3px 12px rgba(0, 0, 0, 0.2);
display: flex;
flex: 0 0 auto;
flex-direction: column;
min-height: 1;
}
.btn {
background-color: #fff;
border-radius: 2px;
border: 1px solid #969499;
box-sizing: border-box;
color: #563d7c;
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: 8px 16px;
text-decoration: none;
vertical-align: middle;
white-space: nowrap; }
.btn:hover {
background-color: #b19dcf; }
white-space: nowrap;
}
.btn:hover {
background-color: #b19dcf;
}
.approve {
padding: 36; }
.approve .status {
font-size: 16px;
color: #969499;
font-weight: lighter; }
.approve .status span {
color: #252526; }
.approve img {
border: 1px solid #969499;
max-width: 100%; }
padding: 36px;
}
.approve .status {
font-size: 16px;
color: #969499;
font-weight: lighter;
}
.approve .status span {
color: #252526;
}
.approve img {
border: 1px solid #969499;
width: 100%;
}
.actions {
margin: 8px 0; }
.actions a {
text-decoration: none;
font-size: 12px;
font-weight: normal; }
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 8px 0;
}
.actions a {
flex: 0 0 auto;
margin-bottom: 8px;
margin-right: 8px;
text-decoration: none;
}
.details {
color: #252526;
border: 1px solid #969499;
border-radius: 2px;
font-size: 12px;
font-weight: normal;
margin: 8px 0;
padding: 16px;
border-radius: 2px;
border: 1px solid #969499; }
.details span {
color: #969499; }
}
.details span {
color: #969499;
}
form.committee {
border-bottom: 1px solid #969499;
padding: 16px;
margin-bottom: 0; }
margin-bottom: 0;
}
section {
color: #969499;
flex: 0 0 auto;
font-weight: lighter;
font-size: 16px;
margin-top: 72;
margin-bottom: -56px;
max-width: 960px;
margin-right: auto;
margin-left: auto; }
margin-top: 36px;
text-align: center;
}
.items {
display: flex;
flex-direction: column;
flex: 1 0 auto;
}
.items a.page {
display: inline-block;
margin: 8px;
text-decoration: none;
color: #563d7c;
font-size: 12px;
float: right; }
float: right;
}
.items a.page:hover {
text-decoration: underline; }
text-decoration: underline;
}
.items a.page.empty {
color: #969499;
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 {
padding: 8px 36;
display: flex;
flex-direction: column;
padding: 8px 36px;
margin: 0px;
border-bottom: 1px solid #969499;
box-sizing: border-box;
width: 100%; }
.item .committee {
color: #969499;
font-size: 12px;
font-weight: bold;
margin: 0px; }
.item a {
text-decoration: none; }
.item .details-row {
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;
width: 100%;
}
.item .committeeAndCost {
align-items: center;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.item .committee {
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;
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 {
position: fixed;
@@ -186,78 +262,98 @@ section {
z-index: 1000;
border-radius: 50%;
text-align: center;
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;
width: 36;
height: 36;
font-size: 28; }
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;
width: 36;
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 {
background-color: #563d7c;
color: #fdd017; }
color: #fdd017;
}
.login {
text-align: center;
color: #fdd017; }
.login div {
margin-top: 30%; }
.login h3 {
font-size: 24px;
margin-bottom: 8px; }
.login h2 {
font-size: 28px;
margin-top: -16px; }
.login .btn {
background-color: #fdd017;
color: #563d7c; }
.login .btn:hover {
background-color: #c69f02; }
color: #fdd017;
}
.login div {
margin-top: 30%;
}
.login h3 {
font-size: 24px;
margin-bottom: 0;
}
.login h2 {
font-size: 28px;
margin: 0 auto;
}
.login .btn {
background-color: #fdd017;
color: #563d7c;
font-size: 16px;
}
.login .btn:hover {
background-color: #c69f02;
}
h1 {
font-size: 18px;
font-weight: lighter;
color: #563d7c;
margin: 16px; }
margin: 16px;
}
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;
color: #969499;
font-weight: lighter; }
}
@media (min-width: 430px) {
form div {
width: 376px; }
form div label {
text-align: right; }
form div input, form div select, form div textarea {
width: 180px;
float: right; } }
@media (min-width: 800px) {
.rcol {
float: right;
width: 40%; } }
.inputRow {
box-sizing: border-box;
margin-bottom: 16px;
padding: 0 36px;
}
.inputRow label {
color: #969499;
font-weight: bold;
font-size: 12px;
margin-left: 2px;
}
.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 */

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>
<body>
<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>
<div>
{% if fincom %}
<a href="/committees">manage</a>
{% endif %}
<a href="/logout">logout</a>
</div>
</div>
<div class="container">
{% block main %}
{% endblock %}
<div class="content">
<div class="container">
{% block main %}
{% endblock %}
</div>
</div>
{% block bottom %}
{% endblock %}

View File

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

View File

@@ -8,7 +8,7 @@
<div class="approve">
{% if I.details %}
<div class="details">
<span>Details:</span><br>
<span>Details</span><br>
{{ I.details }}</div>
{% endif %}
<div class="status">Status: <span>{{ I.statusText }}</span></div>
@@ -23,7 +23,9 @@
<a href="/items" class="btn">Back</a>
</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>

View File

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

View File

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

View File

@@ -1,18 +1,20 @@
<div class="item">
<div class="committee">
{{ I.comName }}
</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 class="committeeAndCost">
<div class="committee">
{{ I.comName }}
</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 }}">
<div class="details-row">
<b>{{ I.event }}:</b>

View File

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

View File

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