diff --git a/README.md b/README.md index 5bf1cb6..bff36e6 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,28 @@ -# Installation - apt install libldap2-dev # reqs - virtualenv venv - . venv/bin/activate - pip install -r requirements.txt - python manage.py migrate - - -## LDAP - sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ADMIN_PASSWORD="toor" -p 389:389 -d nikolaik/openldap - ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f test/testdata.ldif # Testdata - # Verify import - ldapsearch -x -b dc=neuf,dc=no - # Login with test@example.com:test - ## TODO -* Existing members adds membercard to user -* support tablet (1280x800) resolution -* Selected user in form: on select, display user details in register form. +* lookup sms-tables in inside +* register membership in inside-table din_phonenumber, din_usedmembercard, din_user +* Inside auth ### Form * tlf field * validates in javascript with phonenumber-package * onkeyup could shows matching user data from inside (name, expires) -* verify form consistency * submit button * change text to "... and renew" if existing member * grey if form invalid * blue if form valid * grey out on submit -### Other -* Inside auth - -### Backend -* store in inside-table din_phonenumber, din_usedmembercard, din_user -* lookup sms-tables in inside +## Installation + apt install libldap2-dev # reqs + virtualenv venv + . venv/bin/activate + pip install -r requirements.txt + python manage.py migrate +### LDAP + sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ADMIN_PASSWORD="toor" -p 389:389 -d nikolaik/openldap + ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f test/testdata.ldif # Testdata + # Verify import + ldapsearch -x -b dc=neuf,dc=no + # Login with test@example.com:test \ No newline at end of file diff --git a/apps/kassa/forms.py b/apps/kassa/forms.py index 1fd957d..a165d80 100644 --- a/apps/kassa/forms.py +++ b/apps/kassa/forms.py @@ -6,7 +6,7 @@ from django.utils.translation import ugettext_lazy as _ class SearchUserForm(forms.Form): query = forms.CharField( required=False, - widget=forms.TextInput(attrs={'placeholder': _('Search')}) + widget=forms.TextInput(attrs={'placeholder': _('Firstname, lastname, card number or email')}) ) diff --git a/apps/kassa/templates/kassa/register.html b/apps/kassa/templates/kassa/register.html index b295dd9..25625b3 100644 --- a/apps/kassa/templates/kassa/register.html +++ b/apps/kassa/templates/kassa/register.html @@ -2,40 +2,31 @@ {% load i18n bootstrap %} {% block content %}
-
+
{% csrf_token %}

{% trans "Register card" %}

+
    +
  • Add membership for new user
  • +
  • Add membership for existing user
  • +
  • Renew membership for existing user
  • +
  • Register card to existing user [DONE]
  • Replace card for existing user [DONE]
-
    -
  • Renew membership for existing user
  • -
  • Register membership for existing user
  • -
  • Register membership for new user
  • -
-
- -
- - New member -
- New card -
-
-
+
{{ add_card_form|bootstrap }}

Registering a card number with a phone number already tied to an existing user, will add the card to that user.

- +
-
+ diff --git a/static/app/scripts/app.js b/static/app/scripts/app.js index ee47bd4..a44baa4 100644 --- a/static/app/scripts/app.js +++ b/static/app/scripts/app.js @@ -39,7 +39,7 @@ function update_user_with_card_details(user) { } function format_results(results) { results = _.map(results, update_user_with_card_details); - return nunjucks.render('search_results.html', {'results': results}); + return nunjucksEnv.render('search_results.html', {'results': results}); } function render_selected_user(user_data) { var context; @@ -49,12 +49,17 @@ function render_selected_user(user_data) { user_data = update_user_with_card_details(user_data); context = {res: user_data, checked: true}; } - var selected_user_html = nunjucks.render('search_result.html', context); + var selected_user_html = nunjucksEnv.render('search_result.html', context); _dom.selectedUserWrap.html(selected_user_html); } -function set_toast(message) { - //var html = nunjucks.render('toast.html', {'message': message}); - _dom.toastWrap.html(message); +function set_toast(message, message_type) { + var context = { + message: message, + message_type: message_type, + icon: state_to_icon[message_type] + }; + var html = nunjucksEnv.render('toast.html', context); + _dom.toastWrap.html(html); _dom.toastWrap.addClass('visible'); setTimeout(function() { _dom.toastWrap.removeClass('visible'); @@ -83,11 +88,6 @@ function set_field_state(field_element, state, help_text) { help_text = ''; } var help_span = ''+ help_text +''; - var state_to_icon = { - success: 'ok', - warning: 'warning-sign', - error: 'remove' - }; var feedback_span = ''; var css_class = 'has-'+state; var form_group = field_element.parent().parent(); @@ -128,6 +128,9 @@ function resetCardForm(reset_native) { cardForm.fields.cardNumber = false; selectedUser = null; _dom.userIdField.val('').trigger('change'); + + /* Disable submit button */ + _dom.registerSubmitButton.prop('disabled', true); } function cardFormIsValid() { @@ -182,7 +185,7 @@ function getFormData(formElement) { return formData; } - +/* Init and global vars */ var _dom; var users; var selectedUser; @@ -192,6 +195,13 @@ var cardForm = { phoneNumber: false } }; +var state_to_icon = { + success: 'ok', + warning: 'warning-sign', + error: 'remove' +}; +var nunjucksEnv = new nunjucks.Environment(); + $(document).ready(function(){ @@ -215,6 +225,17 @@ $(document).ready(function(){ insideCardNumber: '/inside/cardnumber/', insideRegister: '/inside/register/' }; + /* Add filter |phoneNumber */ + nunjucksEnv.addFilter('phoneNumber', function(str) { + if(!str || str.length <= 1) { + return 'No phone number'; + } + if(str.length == 11) { + return str.slice(0, 3) + " " + str.slice(3, 6) + " " + str.slice(6, 8) + " " + str.slice(8); + } + + return str; + }); /* Phone number as you type */ _dom.phoneNumberField.on('input', function() { @@ -300,7 +321,7 @@ $(document).ready(function(){ /* On search result click */ _dom.results.on('click', '.search-result input', function(e){ - var label = $(this).parent(); + var label = $(this).parent().parent(); var number = label.attr('data-phone-number'); var user_id = label.attr('data-user-id'); @@ -343,17 +364,16 @@ $(document).ready(function(){ type: 'post', headers: {'X-CSRFToken': getCookie('csrftoken')} }).success(function(data){ - console.log("success", data); - set_toast('Success :-)'); + set_toast('Success :-)', 'success'); resetCardForm(true); }).fail(function(data) { console.log("failed", data); - set_toast('Failed!'); + set_toast('Failed!'+ data.error, 'error'); }); }); - /* On user id change */ + /* On user id change */ _dom.userIdField.on('change', function() { /* Render selected user in search form */ if(selectedUser) { @@ -368,10 +388,14 @@ $(document).ready(function(){ }); /* Ninja add some icons to bootstrap form */ - var iconMobile = ''; + var iconMobile = ''; _dom.phoneNumberField.parent().addClass('input-group'); _dom.phoneNumberField.before(iconMobile); + /* Render initial placeholder user */ + var selected_user_html = nunjucksEnv.render('search_result.html', {placeholder: true, res: {number: '+4748105885'}}); + _dom.selectedUserWrap.html(selected_user_html); + /* Initial focus */ if(_dom.usernameField) { _dom.usernameField.focus(); @@ -379,8 +403,6 @@ $(document).ready(function(){ if(_dom.phoneNumberField) { _dom.phoneNumberField.focus(); } - /* Initial submit button state disabled */ - _dom.registerSubmitButton.attr('disabled','disabled'); /* Load query params */ /* FIXME: does not trigger validation and selected user preview */ diff --git a/static/app/styles/app.scss b/static/app/styles/app.scss index d09f0c9..24fef0b 100644 --- a/static/app/styles/app.scss +++ b/static/app/styles/app.scss @@ -1,5 +1,8 @@ $icon-font-path: '../fonts/'; -$green: #5cb85c; +$green-color: #5cb85c; +$red-color: #ff433d; +$yellow-color: #f8ff5b; +$active-color: darkred; /* Vendor styles */ @import "../../bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss"; @@ -49,7 +52,7 @@ input[type=number] { line-height: 46px; } } -.glyphicon-phone { +.glyphicon-phone-large { font-size: 26px; } .register-card-form--selected-user-wrap { @@ -67,7 +70,10 @@ input[type=number] { &.can-register-card:hover { cursor: pointer; } - + .phone-number, + .labels { + margin-left: 21px; + } .label { font-size: 1em; } @@ -76,10 +82,10 @@ input[type=number] { color: #555; } .label-card-yes { - color: $green; + color: $green-color; } .label-is-active { - background-color: darkred; + background-color: $active-color; } [type=radio] { margin-right: 4px; @@ -95,13 +101,28 @@ input[type=number] { } } } +/* Search form */ .selected-icon { visibility: hidden; float: right; - bottom: 48px; + bottom: 66px; + right: 10px; position: relative; - font-size: 1.5em; - color: $green; + font-size: 2em; + color: $green-color; +} +#id_query { + width: 100%; +} +.query-form .form-group { + width: 80%; + display: inline-block; + +} + +.results-wrap { + overflow-y: auto; + max-height: 550px; } /* Footer */ @@ -133,6 +154,18 @@ input[type=number] { visibility: visible; transform: translateY(0); } + .glyphicon { + padding-right: 10px; + } +} +.toast-success { + color: $green-color; +} +.toast-error { + color: $red-color; +} +.toast-warning { + color: $yellow-color; } /* Header */ diff --git a/static/app/templates/search_result.html b/static/app/templates/search_result.html index d107ba4..25a1d44 100644 --- a/static/app/templates/search_result.html +++ b/static/app/templates/search_result.html @@ -1,13 +1,19 @@ {% if not placeholder %} {% if not res.card_number_active %}