diff --git a/.gitignore b/.gitignore index 0dc8c5c9..ad18f5a8 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ manage.py # migrations /rowers/migrations/ /cvkbrno/migrations/ +/survey/migrations/ # secrets config.yaml diff --git a/rowers/admin.py b/rowers/admin.py index cf091c81..26c6d660 100644 --- a/rowers/admin.py +++ b/rowers/admin.py @@ -17,7 +17,8 @@ from .models import ( # Register your models here so you can use them in the Admin module -# Rower details directly under the User + +# Rower details directly under the User class RowerInline(admin.StackedInline): model = Rower can_delete = False @@ -73,7 +74,7 @@ class UserAdmin(admin.ModelAdmin): ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions',)}),) - + search_fields = ["username","first_name","last_name","email"] def rowerplan(self, obj): @@ -90,7 +91,7 @@ class FavoriteChartAdmin(admin.ModelAdmin): class C2WorldClassAgePerformanceAdmin(admin.ModelAdmin): list_display = ('sex','weightcategory','age','distance','power','name','season') - + class SiteAnnouncementAdmin(admin.ModelAdmin): list_display = ('announcement','created','modified','expires','dotweet') @@ -99,7 +100,7 @@ class TeamAdmin(admin.ModelAdmin): class TeamInviteAdmin(admin.ModelAdmin): list_display = ('issuedate','team','user','code') - + class TeamRequestAdmin(admin.ModelAdmin): list_display = ('issuedate','team','user','code') @@ -136,7 +137,7 @@ class IndoorVirtualRaceResultAdmin(admin.ModelAdmin): class PaidPlanAdmin(admin.ModelAdmin): list_display = ('name','shortname','price','paymenttype','paymentprocessor','external_id') - + admin.site.unregister(User) admin.site.register(User,UserAdmin) admin.site.register(Workout,WorkoutAdmin) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index c1120f33..4ab15697 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -47,6 +47,7 @@ ALLOWED_HOSTS = CFG['allowed_hosts'] INSTALLED_APPS = [ 'rowers', + 'survey', # 'cvkbrno', 'django.contrib.admin', 'django.contrib.auth', diff --git a/rowsandall_app/urls.py b/rowsandall_app/urls.py index ec1b60df..b6bcca18 100644 --- a/rowsandall_app/urls.py +++ b/rowsandall_app/urls.py @@ -22,6 +22,7 @@ from django.views.generic import TemplateView from rowsandall_app.views import rootview, landingview from django.contrib.auth import views as auth_views from rowers import views as rowersviews +from survey import views as surveyviews import django @@ -65,6 +66,7 @@ urlpatterns += [ {'next_page': '/'}, name='logout',), re_path(r'^rowers/',include('rowers.urls')), + re_path(r'^survey/',include('survey.urls')), # re_path(r'^cvkbrno/',include('cvkbrno.urls')), # re_path(r'^admin/rq/',include('django_rq_dashboard.urls')), re_path(r'^call\_back',rowersviews.rower_process_callback), diff --git a/survey/__init__.py b/survey/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/survey/admin.py b/survey/admin.py new file mode 100644 index 00000000..29051dbc --- /dev/null +++ b/survey/admin.py @@ -0,0 +1,21 @@ +from .models import Response +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin + +class ResponseInline(admin.StackedInline): + model = Response + fieldsets = ( + ('User Details',{'fields':('plan','username','email')}), + ('Used Features', + {'fields:': + ('logging','technical', + 'trend','planning','racing','coaching','export','video','interval')}), + ('Paid Plan Questions', + {'fields':('capabilities','fallshort','considered','features')}) + ) + +class ResponseAdmin(admin.ModelAdmin): + #inlines = (ResponseInline,) + list_display = ('plan','id','date','capabilities') + +admin.site.register(Response,ResponseAdmin) diff --git a/survey/apps.py b/survey/apps.py new file mode 100644 index 00000000..58263d6c --- /dev/null +++ b/survey/apps.py @@ -0,0 +1,4 @@ +from django.apps import AppConfig + +class SurveyConfig(AppConfig): + name = 'app' diff --git a/survey/models.py b/survey/models.py new file mode 100644 index 00000000..00284a9c --- /dev/null +++ b/survey/models.py @@ -0,0 +1,125 @@ +from django.contrib.auth.models import User +from django import forms +from django.forms import ModelForm + +from django.conf import settings +from django.db import models +from django.utils import timezone + +from rowers.database import * +import datetime + +def current_day(): + return (datetime.datetime.now(tz=timezone.utc)).date() + +class Response(models.Model): + planchoices = ( + ('basic','Free Athlete'), + ('freecoach','Free Coach'), + ('pro','Pro'), + ('plan','Self-Coach'), + ('coach','coach'), + ) + plan = models.CharField(max_length=150,choices=planchoices,default='basic') + username = models.CharField(max_length=150,unique=True,verbose_name='User Name',blank=True,null=True) + email = models.EmailField(max_length=150,verbose_name='User Email',blank=True,null=True) + date = models.DateField(default=current_day,verbose_name='survey date') + nrworkouts = models.IntegerField(default=0,verbose_name='nr of workouts per week') + nrworkoutsR = models.IntegerField(default=0,verbose_name='nr of workouts per week on Rowsandall') + + hearchoices = ( + ('wordofmouth','Word of mouth'), + ('socialmedia','Social Media (Facebook, Twitter)'), + ('otherinternet','Other internet'), + ('coach','From my Coach/Coachee'), + ('other','Other') + ) + + heard = models.CharField(max_length=150,blank=True,null=True, + default=None, + choices=hearchoices,verbose_name="How did you hear about Rowsandall") + + logging = models.BooleanField(default=False,verbose_name='Logging Workouts') + technial = models.BooleanField(default=False,verbose_name='Technical Analysis of workouts') + trend = models.BooleanField(default=False,verbose_name='Trend Analysis of workouts') + planning = models.BooleanField(default=False,verbose_name='Training planning') + racing = models.BooleanField(default=False,verbose_name='Online racing') + coaching = models.BooleanField(default=False,verbose_name='Coaching') + export = models.BooleanField(default=False,verbose_name='Exporting data to other sites') + video = models.BooleanField(default=False,verbose_name='Video Analysis') + interval = models.BooleanField(default=False,verbose_name='Interval editor') + + capabilities = models.NullBooleanField(default=None,null=True,blank=True, + verbose_name='Did you get the capabilities and features that you expected out of Rowsandall') + + fallshort = models.TextField(max_length=300,blank=True,verbose_name='Where did Rowsandall fall short of your expectations?') + + considerchoices = ( + ('no','No'), + ('pro','Yes: Pro'), + ('plan','Yes: Self-Coach'), + ('coach','Yes: Coach') + ) + + considered = models.CharField(max_length=150,choices=considerchoices,default=None,null=True,blank=True, + verbose_name='If you are on a Free plan, did you consider one of the paid plans?') + + features = models.TextField(max_length=300,blank=True, + verbose_name="What combination of features would entice you to upgrade to a paid plan") + + agreechoices = ( + ('completely_disagree','Completely Disagree'), + ('disagree','Disagree'), + ('neutral','Neither agree nor disagree'), + ('agree','Agree'), + ('completely_agree','Completely Agree'), + ) + + pricing = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="The pricing for plans is clear and understandable" + ) + + subscription = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like I get a good value for the price of the subscription" + ) + + advanced = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the advanced features of Rowsandall are easy to use" + ) + + mobile = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="It is easy to use Rowsandall from a mobile device" + ) + + developer1 = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the developer of Rowsandall is responsive to problems and resolves them quickly" + ) + + developer2 = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the developer of Rowsandall is responsive to ideas for new features and capabilities" + ) + + sugchoices = ( + ('bug','Resolve a bug'), + ('newfeature','Add a new feature'), + ('improve','Improve the ease of use of the site'), + ('easy','Make the site easier to use on mobile devices'), + ('other','Other') + ) + + bug = models.BooleanField(default=False,verbose_name='Resolve a bug') + newfeature = models.BooleanField(default=False,verbose_name='Add a new feature') + improve = models.BooleanField(default=False,verbose_name='Improve the ease of use of the site') + easu = models.BooleanField(default=False,verbose_name='Make the site easier to use on mobile devices') + other = models.BooleanField(default=False,verbose_name='Other') + + suggestiontext = models.TextField( + max_length=300,default=None,null=True,blank=True, + verbose_name='My suggestion is (please write a short description of your suggestion)' + ) diff --git a/survey/urls.py b/survey/urls.py new file mode 100644 index 00000000..90cb2d20 --- /dev/null +++ b/survey/urls.py @@ -0,0 +1,10 @@ +from django.conf import settings +from django.conf.urls import url, include +from django.urls import path, re_path + +import survey.views as views + +urlpatterns = [ +#re_path(r'^responses/$',views.ResponseList.as_view(),name='responses_view'), +#re_path(r'^response/(?P\d+)/$',views.ResponseDetail.as_view(),name='response_view') +] diff --git a/survey/views.py b/survey/views.py new file mode 100644 index 00000000..7a3e6c99 --- /dev/null +++ b/survey/views.py @@ -0,0 +1,34 @@ +from django.shortcuts import render +from django.template.loader import render_to_string + +from django.views.generic.edit import UpdateView,DeleteView,CreateView +from django.views.generic import ListView,DetailView + +from django.http import ( + HttpResponse, HttpResponseRedirect, + JsonResponse, + HttpResponseForbidden, HttpResponseNotAllowed, + HttpResponseNotFound,Http404 + ) +from django.contrib.auth import authenticate, login, logout + +from survey.models import Response + +class ResponseList(ListView): + model = Response + template_name = 'response_list.view' + +class ResponseCreate(CreateView): + login_required = True + model = Response + template_name = 'response_create.html' + +class ResponseUpdate(UpdateView): + login_required = True + model = Response + template_name = 'response_update.html' + +class ResponseDetail(DetailView): + login_required = True + model = Response + template_name = 'response.html'