From f919dbde275f8bafe6a2ad227325f3907c1b5893 Mon Sep 17 00:00:00 2001 From: Alex Buchanan Date: Fri, 24 Sep 2010 05:24:28 -0700 Subject: [PATCH] Customer Care templates --- apps/customercare/helpers.py | 10 + .../templates/customercare/base.html | 4 + .../templates/customercare/landing.html | 50 ++ .../templates/customercare/reply_modal.html | 47 ++ apps/customercare/urls.py | 3 +- apps/customercare/views.py | 120 ++++- media/css/customercare.css | 351 +++++++++++++ media/img/customercare/bubble-choose.png | Bin 0 -> 5165 bytes media/img/customercare/bubble-respond.png | Bin 0 -> 5232 bytes media/img/customercare/bubble-signin.png | Bin 0 -> 5118 bytes media/img/customercare/expander-closed.png | Bin 0 -> 264 bytes media/img/customercare/expander-open.png | Bin 0 -> 279 bytes media/img/customercare/hr-line.png | Bin 0 -> 280 bytes .../img/customercare/initial-tweet-arrow.png | Bin 0 -> 205 bytes media/img/customercare/nurse.png | Bin 0 -> 27330 bytes media/img/customercare/popup-background.png | Bin 0 -> 118 bytes media/img/customercare/reply-arrow.png | Bin 0 -> 366 bytes media/img/customercare/reply-check.png | Bin 0 -> 648 bytes media/img/customercare/sumo-logo.png | Bin 0 -> 4268 bytes media/img/customercare/twitter-icon.png | Bin 0 -> 10727 bytes .../img/customercare/wantgetinvolved-back.png | Bin 0 -> 4905 bytes media/js/customercare.js | 56 ++ media/js/libs/jquery.NobleCount.js | 480 ++++++++++++++++++ media/js/libs/jqueryui.min.js | 32 +- migrations/44-cannedresponses-initialdata.sql | 50 +- requirements/prod.txt | 2 + settings.py | 14 + urls.py | 2 +- 28 files changed, 1192 insertions(+), 29 deletions(-) create mode 100644 apps/customercare/helpers.py create mode 100644 apps/customercare/templates/customercare/base.html create mode 100644 apps/customercare/templates/customercare/landing.html create mode 100644 apps/customercare/templates/customercare/reply_modal.html create mode 100644 media/css/customercare.css create mode 100644 media/img/customercare/bubble-choose.png create mode 100644 media/img/customercare/bubble-respond.png create mode 100644 media/img/customercare/bubble-signin.png create mode 100755 media/img/customercare/expander-closed.png create mode 100755 media/img/customercare/expander-open.png create mode 100755 media/img/customercare/hr-line.png create mode 100755 media/img/customercare/initial-tweet-arrow.png create mode 100644 media/img/customercare/nurse.png create mode 100755 media/img/customercare/popup-background.png create mode 100755 media/img/customercare/reply-arrow.png create mode 100755 media/img/customercare/reply-check.png create mode 100644 media/img/customercare/sumo-logo.png create mode 100644 media/img/customercare/twitter-icon.png create mode 100644 media/img/customercare/wantgetinvolved-back.png create mode 100644 media/js/customercare.js create mode 100644 media/js/libs/jquery.NobleCount.js diff --git a/apps/customercare/helpers.py b/apps/customercare/helpers.py new file mode 100644 index 00000000000..46229f7109e --- /dev/null +++ b/apps/customercare/helpers.py @@ -0,0 +1,10 @@ +from datetime import datetime + +from django.template import defaultfilters + +from jingo import register + + +@register.filter +def utctimesince(time): + return defaultfilters.timesince(time, datetime.utcnow()) diff --git a/apps/customercare/templates/customercare/base.html b/apps/customercare/templates/customercare/base.html new file mode 100644 index 00000000000..eec00df0eef --- /dev/null +++ b/apps/customercare/templates/customercare/base.html @@ -0,0 +1,4 @@ +{# vim: set ts=2 et sts=2 sw=2: #} +{% extends "common/base.html" %} +{% set styles = ('customercare',) %} +{% set scripts = ('customercare',) %} diff --git a/apps/customercare/templates/customercare/landing.html b/apps/customercare/templates/customercare/landing.html new file mode 100644 index 00000000000..06ce9fbfefa --- /dev/null +++ b/apps/customercare/templates/customercare/landing.html @@ -0,0 +1,50 @@ +{# vim: set ts=2 et sts=2 sw=2: #} +{% extends "customercare/base.html" %} +{% set title = _('Join our Army of Awesome') %} + +{% block breadcrumbs %}{% endblock %} + +{% block content_area %} +
+

Join our
Army of Awesome

+

Love Firefox and have a few moments to help? Help other Firefox users on Twitter. Good things will come to those who tweet!

+
+ +
+
    +
  1. Choose a tweet below
  2. + +
  3. Respond to the tweet!
  4. +
+
+
+ +
+
+

Choose a tweet to help

+
+ +
+ + +
+ +
+ {% include 'customercare/reply_modal.html' %} +
+ +
+

Sign in with your Twitter account

+

Before you join the Army of Awesome, you need to log in so you can respond to tweets. You will now be redirected to Twitter to log in.

+ Sign in + Cancel +
+{% endblock %} diff --git a/apps/customercare/templates/customercare/reply_modal.html b/apps/customercare/templates/customercare/reply_modal.html new file mode 100644 index 00000000000..24a1ec0a6da --- /dev/null +++ b/apps/customercare/templates/customercare/reply_modal.html @@ -0,0 +1,47 @@ +
+
+ + + + + + +
+ +
+

What is your reply about?

+
+ {% for resp in canned_responses %} +

{{ resp.title }}

+
+
    + {% for topic in resp.responses.all() %} +
  • + {{ topic.title }} + {{ topic.response }} #fxhelp +
  • + {% endfor %} +
+
+ {% endfor %} +
+ + +
+ +
+

Get personal

+
+
140
+
+ + +
+ + Your message was sent! + +
+
+
+
+ diff --git a/apps/customercare/urls.py b/apps/customercare/urls.py index 25f27cf3a46..4acd2e50aad 100644 --- a/apps/customercare/urls.py +++ b/apps/customercare/urls.py @@ -1,5 +1,6 @@ from django.conf.urls.defaults import patterns, url urlpatterns = patterns('customercare.views', - url(r'^$', 'landing', name='customercare.landing'), + url(r'/twitter_auth', 'twitter_auth', name="customercare.twitter_auth"), + url(r'', 'landing', name='customercare.landing'), ) diff --git a/apps/customercare/views.py b/apps/customercare/views.py index 94edcd5d660..175a7956780 100644 --- a/apps/customercare/views.py +++ b/apps/customercare/views.py @@ -1,6 +1,124 @@ +from datetime import datetime +from email.Utils import parsedate +import json +import logging +from uuid import uuid4 + from django import http +from django.conf import settings +from django.core.cache import cache + +import jingo +import tweepy + +from .models import CannedCategory, Tweet + + +log = logging.getLogger('custcare') + +token_cache_prefix = 'custcare_token_' +key_prefix = token_cache_prefix + 'key_' +secret_prefix = token_cache_prefix + 'secret_' + +# cookie names are duplicated in js/cusomtercare.js +access_cookie_name = 'custcare_twitter_access_id' +redirect_cookie_name = 'custcare_twitter_redirect_flag' + + +def auth_factory(request): + return tweepy.OAuthHandler(settings.TWITTER_CONSUMER_KEY, + settings.TWITTER_CONSUMER_SECRET, + 'https://{0}/{1}/customercare/'.format( + request.get_host(), request.locale)) + + +def set_access_cookie(resp, id): + resp.set_cookie(redirect_cookie_name, '1', httponly=True) + resp.set_cookie(access_cookie_name, id, secure=True) + + +def set_tokens(id, key, secret): + cache.set(key_prefix + id, key) + cache.set(secret_prefix + id, secret) + + +def get_tokens(id): + key = cache.get(key_prefix + id) + secret = cache.get(secret_prefix + id) + return key, secret def landing(request): """Customer Care Landing page.""" - return http.HttpResponse(landing.__doc__) + + canned_responses = CannedCategory.objects.all() + tweets = [] + for tweet in Tweet.objects.filter(locale='en')[:10]: + data = json.loads(tweet.raw_json) + parsed_date = parsedate(data['created_at']) + date = datetime(*parsed_date[0:6]) + tweets.append({ + 'profile_img': data['profile_image_url'], + 'user': data['from_user'], + 'text': tweet, + 'date': date, + }) + + resp = jingo.render(request, 'customercare/landing.html', { + 'canned_responses': canned_responses, + 'tweets': tweets, + 'now': datetime.utcnow(), + }) + + # TODO HTTP redirect flag checking? + if request.COOKIES.get(redirect_cookie_name): + return http.HttpResponseRedirect('https://{0}/{1}'.format( + request.get_host(), request.get_full_path())) + + # if GET[oauth_verifier] exists, we're handling an OAuth login + verifier = request.GET.get('oauth_verifier') + if verifier: + auth = auth_factory(request) + request_key = request.COOKIES.get('request_token_key') + request_secret = request.COOKIES.get('request_token_secret') + if request_key and request_secret: + resp.delete_cookie('request_token_key') + resp.delete_cookie('request_token_secret') + auth.set_request_token(request_key, request_secret) + + try: + auth.get_access_token(verifier) + except tweepy.TweepError: + log.warning('Tweepy Error with verifier token') + pass + else: + access_id = uuid4().hex + set_access_cookie(resp, access_id) + set_tokens(access_id, auth.access_token.key, auth.access_token.secret) + + return resp + + +def twitter_post(request): + # access_id = request.COOKIES.get(access_cookie_name) + # if access_id: + # key, secret = get_tokens(access_id) + # authed = True + # resp.write('key: %s sec: %s' % (key, secret)) + # set_access_cookie(resp, access_id) + pass + + +def twitter_auth(request): + auth = auth_factory(request) + + try: + redirect_url = auth.get_authorization_url() + except tweepy.TweepError: + log.warning('Tweepy error while getting authorization url') + return http.HttpReponseServerError() + + resp = http.HttpResponseRedirect(redirect_url) + resp.set_cookie('request_token_key', auth.request_token.key, max_age=3600, secure=True) + resp.set_cookie('request_token_secret', auth.request_token.secret, max_age=3600, secure=True) + return resp diff --git a/media/css/customercare.css b/media/css/customercare.css new file mode 100644 index 00000000000..4e4b6f54200 --- /dev/null +++ b/media/css/customercare.css @@ -0,0 +1,351 @@ +body { + background-position: 50% 0; +} + +.feature-contents { + width: 640px; + background: url("../img/customercare/nurse.png") no-repeat scroll right 20px transparent; + padding: 30px 0 0 25px; +} + +.feature-contents h2, .feature-contents h3 { + line-height: 1em; + margin-right: 250px; +} + +.feature-contents h2 { + color: #FFF; + font-size: 46px; +} + +.feature-contents h3 { + color: #68645b; + line-height: 1.5em; + font-size: 150%; + margin-top: 15px; +} +#speach-bubbles { + padding: 60px 0 15px 25px; +} +#speach-bubbles li { + list-style-type: none; + float: left; + text-indent: -99999px; + width: 177px; + height: 97px; +} +#speach-bubbles li.choose { + background: url("../img/customercare/bubble-choose.png") no-repeat scroll top left transparent; +} +#speach-bubbles li.signin { + background: url("../img/customercare/bubble-signin.png") no-repeat scroll top left transparent; +} +#speach-bubbles li.respond { + background: url("../img/customercare/bubble-respond.png") no-repeat scroll top left transparent; +} +#tweetcontainer { + border: 1px solid #f5f5f5; + padding: 2px; + clear: both; +} +#tweetcontainer h2 { + margin: 0px; + padding: 0px; + float: left; + line-height: 3em; + font-weight: bold; + font-size: 20px; + background: none; +} +#tweetcontainer img { + float: left; + padding: 4px; +} +.tweets-header { + padding-left: 15px; +} +#tweets { + margin: 0 0 15px 15px; +} +#tweets ul { + margin: 0px; +} +#tweets li { + width: 630px; + border-top: 1px solid #ccc; + overflow: auto; + margin-bottom: 0px; + padding: 10px; + cursor: pointer; +} +#tweets li.alt { + background: -moz-linear-gradient(top, #fff, #f5f5f5); +} +#tweets li:hover { + border-top: 1px solid #fef1ad; + background: -moz-linear-gradient(top, #fffffd, #fdefa6); +} +#tweets li img { + float: left; + margin-right: 1em; + border: solid 1px #cacccb; + padding: 0px; + width: 48px; + height: 48px; +} +#tweets li span { + display: block; +} +#tweets li span { + color: #307fc1; + text-decoration: none; + font-weight: bold; + font-size: 13px; + line-height: 1.4em; +} +#tweets li span .time { + float: right; + font-weight: normal; + font-style: italic; + font-size: 12px; + color: #afaba3; +} +#tweets li span .text { + font-weight: normal; + font-size: 14px; + color: #69645b; +} +.tweets-buttons { + float: right; + line-height: 4em; + padding-right: 15px; +} +.tweet a, .tweet a:hover { + color: #69645b; + text-decoration: none; +} +.hidden { + display: none; +} + +/* reply page styling */ +#reply-modal { display: none; } + +#reply-container { + background-color: #e6f2f6; + width: 444px; + margin: 0 auto; + padding: 30px 24px; + top: 86px; + font-family: Verdana, sans-serif; + text-align: left; + + -moz-box-shadow: 0 0 10px #aaa; + box-shadow: 0 0 10px #aaa; +} + +#reply-container, +#reply-container #replies { + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +#initial-tweet img { + border: 1px solid #bbb; + float: left; +} + +#initial-tweet .box { + border: 1px solid #aaa; + display: block; + margin-left: 70px; + text-align: left; + padding: 6px 9px 10px 9px; + color: #69645b; + font-size: 80%; + background: #fff; +} + +#initial-tweet a { + color: #2276bb; + display: block; + text-decoration: none; + font-weight: bold; +} + +#initial-tweet .box a { + padding-bottom: 4px; +} + +#initial-tweet #arrow { + border: 0; + position: absolute; + left: 88px; + top: 65px; +} + +#reply-container h4 { + font-family: Verdana, sans-serif; + color: #4b4740; + font-size: 125%; + font-weight: normal; + margin-bottom: 15px; +} + +#reply-container #replies { + background: #8fc1da; + background: -moz-linear-gradient(center top , #8fc1da, #e5f1f7) repeat; + margin-top: 20px; + padding: 15px 20px; +} + +#reply-container h3.ui-accordion-header { + background: #f0f0f0 url('../img/customercare/expander-closed.png') 8px 50% no-repeat; + border: 1px solid #b2b2b2; + font-family: Verdana, sans-serif; + font-size: 12px; + padding: 4px 0 5px 24px; + margin: 0 0 9px 0; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +#reply-container h3.ui-accordion-header a { + color: #afaba3; + display: block; +} + +#reply-container h3.ui-accordion-header a:hover { + text-decoration: none; +} + +#reply-container #replies ul { + margin: 0 0 10px 24px; + list-style-type: none; +} + +#reply-container #replies li a { + display: block; + color: #0489b7; + padding-bottom: 2px; +} + +#reply-container h3.ui-accordion-header.ui-state-default { + background: #f0f0f0 url('../img/customercare/expander-closed.png') 8px 50% no-repeat; +} + +#reply-container h3.ui-accordion-header.ui-state-active { + background: #f0f0f0 url('../img/customercare/expander-open.png') 8px 50% no-repeat; +} + +#reply-container h3.ui-accordion-header.ui-state-default a { + font-weight: normal; + color: #afaba3; +} + +#reply-container h3.ui-accordion-header.ui-state-active a { + font-weight: bold; + color: #69645b; +} + +#accordion .ui-widget-content { + background: none; + border: none; +} + +.topics .snippet { + display: none; +} + +#reply { + padding-bottom: 34px; +} + +#reply .reply-message { + width: 310px; + height: 65px; + border: 1px solid #aaa; + padding: 10px 15px; + color: #afaba3; + background: #fff; + font-size: .9em; +} + +#reply #reply-arrow { + position: relative; + left: 30px; + top: 4px; + display: inline; +} + +#reply .submit-message { + display: none; + background: url('../img/customercare/reply-check.png') right top no-repeat; + font-weight: bold; + color: #4b4740; + height: 21px; + padding-right: 23px; + padding-top: 3px; + float: left; + margin-top: 14px; +} + +#reply .container { + position: relative; + top: -12px; +} + +#reply .submitButton { + background: -moz-linear-gradient(center top, #eed052 15px, #ebb04f 18px, #e79f30, #e0752b); + border-left: 1px solid #d4661a; + border-right: 1px solid #d4661a; + border-top: 1px solid #d19f7c; + border-bottom: 1px solid #ba5c1c; + color: #b01a04; + width: 140px; + height: 36px; + margin-top: 10px; + float: right; + + text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.6); + -moz-box-shadow: 0 0 5px #777; + box-shadow: 0 0 5px #777; + + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + + cursor: pointer; +} + +#reply .character-counter { + width: 50px; + color: #fff; + font-weight: bold; + font-size: 24px; + float: right; + position: relative; + top: 33px; +} + +.hrbreak { + background: url('../img/customercare/hr-line.png') center 20px no-repeat; + height: 50px; +} +/* end of reply page styling */ + +.notice { + background-color:#FFFFCC; + border:2px solid orange; + margin:1em 0; + padding:1em; + text-align:center; + float: left; +} + +#twitter-modal { + display: none; +} diff --git a/media/img/customercare/bubble-choose.png b/media/img/customercare/bubble-choose.png new file mode 100644 index 0000000000000000000000000000000000000000..651109e989af2607095d91f395ec96bd5034f4b2 GIT binary patch literal 5165 zcmeHLcTiK=9!6L}(aI)Vg2R5T<30wIAUger;>r0v=O(L6*1 z1w=qly3(Xq=^Y_bq=q7dDlfRM``(**GwUDkk2m9)x#!$_f8Y6jzw@1M?wq;7W~O=o z(Y>Mq0s;U7eVx<%F`a+mwg~b2)T$R9{9zA6*P3BLwP$$XXhZ=m0@aQPG;qN=5Kj|v z1TVKLqPl>P&M43yMOmAe0Wnk>5vT};gW>XcC_(|KqySb>f+OIHCxCD$R0RT6hA2Sg zVJb+d5>gQc{MtZhQJ^}FV2?blbMk9C{u2u1$Y8i4ArKD_53q*%ajp;;7z+7UFaiG!>*`J;e<_22hY-m`7b1m0=i_1jhIe(OGN^P%>VHY`E&Nv^ zzR*Yvjfi7VX;>s)lJ{~)B5`Q=g*&4R#p}k7FJhR-?6-NP9oOU)|Qr*W@l$Ve*Cz+yxh~%Ggk8Y z)2C03jg942daW$4tYf?0F&*<&kBp6t^~bU2`}>OZ5%1r>U!I<7Zf-6%)8IDN4ZTe6 z4iBlZw_aRaAh;8Xq5@o}T7%xf2r;larIf!^5qu zt+{&2BO@biZEam$UHy5PuVkfO9+k{jmRX+RayXna3(V-~Xm4+C)~`Er^pu;Lnrhz` z7wW(V2M62R+lPjRGG%vUsUPp?=xAwa8K|!*(pBj0?#?q%ndkIZJKOg4^>LD7JHq@M zS>A66R;Aaxa`lz#lj54M(CYGXx|8E;{h5t717FHY)p?OCN#}FXC*D%*-q@N~#Xl?w z@y}8_R_j`bO-70C&eQMbFB-c|a#^**>g+SXEV$)e1Q z(v*_WdMCKOw79dgb7^|&6;!%CKYJ)Et?%i>a@$iy?oO4rZe%MSs(hZ%(Zy41OopW=3!Fha2&v zvnO4s9zMK2AMP7o-^$y*I2ocK>&DTPHN_EePG!hkbEDko{#a|Bv&SQ9?3>dw$%uP~ zlK9<%BN?NnagORv~F9M(8e! z?)kyd)0cm}d&-$$B=p|CtjiC5=7HQ9#f&G1&0k+C>v_oTIRhCs|3&kBBFeF>PkK)` z!b%S42EMS?WO%h#$?MXyXAInsXc_yCrtehr=+a|aMnuXg@koiSii)~r)iCW$-ZCB@ z#O-i~45h?kbLlQvI?D{>i&-0?H& zKq+ZZRa>gi;%$F(My{CVe&{qv>_bC%#0A3(aZ+GyLz!M%wa4M`iS6|^Wp9o$p>d*W z)!NuJg!qvl(~4Dl}8X3UcMU{uAg>FreQMDO*#Fh z=$3c6wTWl9>f($nEo!Mr@ z2y`@2I%iDjGQh5)GHRvnHV1L!qgDeP``cOF>IYGWuolioXO*2U*!f+7v&;my+A&OoL`gQh>X1udOQ%C%LT`mJ zEB^RJSSABtrP~5l&kRdSNh?`0e&;h* zgH)6|{=z}DlrCxB0#n zp@()s`%yBxDT7Q&x_eWX9T&7aDs0*B?9gYG^4y;} zeJmnG_GyOYwwN*-q_DLWiqI+_2awp7In)bc?#;OBKR6DG9oDQUKhps<3noh@_o|k) zC$dV_i&6l_el<~J!nlTEJQyb&I77Hq18qOP9w4X}UzK?Tpjkjn+^eH)CaKxjoF@=R^*Y+x5KZdXS%{ zIbQo2(^DF!Ody07)mX+;zl%~qF$Ylj zD(5U6(lc5+3kyRvrg!LNpNc#>+lj5N9+n-x67mMjEL1_$?7$Y4oA{rm=mUQ1_dSIQ zd7ZZpG|yF+jm49)%#tAmtK~v4=JcFig~x;(U?ANDXiAjZu`Lw8?l-%ft9CC^jB49y zn#!AzRpzybLDqPSjg6Bs%}ojGlUC>p5xfOuy=9yT#MG23*DCu=ILB?a z&@2g12d)hdY=5<4g{H1Ij1HjBlAfZ~Zo~AN*oCQPwM$MZDzH~sm**O3eGv4)F}BH0 z=T_gm8KcdZ=l7dg+I|-naLUtl7e`hcS=!#65Nk#H@q0C?4QQ2?t*eZzm`I_Xqtt!r zfwl=QBoXu+XpvI~dgKPZ$oRseB literal 0 HcmV?d00001 diff --git a/media/img/customercare/bubble-respond.png b/media/img/customercare/bubble-respond.png new file mode 100644 index 0000000000000000000000000000000000000000..c1d4721f7605331ebf3edaedc7b9818517e88df9 GIT binary patch literal 5232 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 literal 0 HcmV?d00001 diff --git a/media/img/customercare/bubble-signin.png b/media/img/customercare/bubble-signin.png new file mode 100644 index 0000000000000000000000000000000000000000..54121f9e3582d257b6765fb5848bd83f470198d1 GIT binary patch literal 5118 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 literal 0 HcmV?d00001 diff --git a/media/img/customercare/expander-closed.png b/media/img/customercare/expander-closed.png new file mode 100755 index 0000000000000000000000000000000000000000..e6a96f0eda1b9a9544194f54da101cb723dc7305 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1|(OmDOUqhk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XR(ZNOhE&|@nXsR$*+Agf{uZGVN`5onaCgXl{VTt~Ds;Pr zn^Af|M?r2B)5=@+_8dER*W9TUcXRnMJ$RPSWtX5+0-LtXd;atDv&@gzzF&xHj#HS& zalh}<J({`jhf z?(S|yUFGSHQEqL5Ya$#2I~`-3njRk5XDiY5diE{J9Xoakp8N6ry?nA;m|gR>KDn+# zZ|*3ug_`oRB`6pi68-=4bNj>F+w*%`kBahead{=Qe(TfYc{c4D&;GiwpMSzY;zn4zIz$kBw=GiFFcL`MEs)^-W>nOwle aVZhL4?))qDlZiCY6AYfNelF{r5}E)&X>aKO literal 0 HcmV?d00001 diff --git a/media/img/customercare/hr-line.png b/media/img/customercare/hr-line.png new file mode 100755 index 0000000000000000000000000000000000000000..e402051aaa5b73aeb65ef1cebc85895b169132f0 GIT binary patch literal 280 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 literal 0 HcmV?d00001 diff --git a/media/img/customercare/popup-background.png b/media/img/customercare/popup-background.png new file mode 100755 index 0000000000000000000000000000000000000000..81abc796c6ae42683efb15c9e286eb20a5ff08f0 GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%NqD+AhE&{2`t$$)e;+oL14kOzIJg;DBpBYDW1cr7?b#2Y O8U{~SKbLh*2~7YP0we$c literal 0 HcmV?d00001 diff --git a/media/img/customercare/reply-arrow.png b/media/img/customercare/reply-arrow.png new file mode 100755 index 0000000000000000000000000000000000000000..0b8d990455c9c9e869bc24019968fd3e02e18e21 GIT binary patch literal 366 zcmV-!0g?WRP)GvTH{nyvM8Gg7AYNf@ZN+S5WyuU;L&eB4&MFe0NI>C zv2{SKOR9nDK)l7+*oa43S_&=*VjCFf^8=Z?fLMiC1Eqm@ub!T+sGOV}hNPmRB7?53 zjs%do9f(B<83@&j*1TmI^B!FSVKq>%+HG`6p5-6=s zh9&IDK!FgD1i3(8UytGc|Noiy@85sNaQ^&-|I`3KfByUrG7BKU0Ja`_A;jBv4gdfE M07*qoM6N<$f;*;DSr z1<%~X^wgl##FWaylc_cg42*&SJ|V7+7m}JUrrv+|rS)QZ!-b@V^NIB!l+bl4ulsWT zq-zy>9`Ahc{&UNP^!}?Qn;)#)`FQ31cb}(UZ`%H7_0`vp8ZRVtUe1|)v-$Shcc)&Q zS#YzfvcWwl<)xcd6e-FI&rFC;f#Ogr#w*P-WoF1@;4doHf>Y{dO{pN>60 z(0DO<g9?H=Iwp`}X65_g^MouYB}jrL5cU9xb^uq3J^MwnuC3zx&v9 zA?5zNuQ5v-je#K;T@vIM{GVokVa~4|dw|v~^K@|xskoJL+F8uSQNZQmue{saa&Maz z{pWsZzvfimLFqfiO$>XpUP}G>Wz%A2SHHWsnbn}eq-|NcoWzsUbGC%{9$bE6=9&XZ zHL5$54kS$!e!{D;XOD=j!W@fEUV&?`9-k9Pb_(Nb*l_=uxJRu&~gWJwT$Yy&941q?}pd4_aIS_s62AOcSj z2HY?Rii#|X2#O0Li;8GqBBF@GL>LwYM3hBk5txQi=Dk<-s>UDlW2(4S-M72HbIz#L~MIu8mYamO(vS)dphjY3&k$;4dVb`S>qzyN`W zfq#3m1P=)K47`__GsRiV1h)ws!X%(an2RSbY&*|_kGEQbwUp5jf`myJ{W&cOnuJc&RI3m_3N&dK$IcEAig9*F~A<`O8LBo|3P z>xC#smT|>oDv3h=PcWZ1i52gV2q((m^T?nO35;Hz(3aR6Kdy8RXB_KwL?lwB`7E|MhJu z$yaGSCD)W(U!}lTfv4OxCD&Ie@KxX`cm2KO!v1lv1x3hdHUv4g?jKeAB1hgw?CuXPT= zvSa@LitQO5&1@S~{yLCy>gxHN(ujR&;@bX}*3KI@D{G%NJ?Z_#y5D1d_ucHvCwD)8 z&#ms8aWUkZE19}ii}bJEn|6UW=Xy1+Ab;ki1JiQ?zb$OV=TIapRx0?^D zTBZB56=}EpDmrK79oh4+D=xj5T3Qo+rTWLp4!`1G!?PPkeR&~9v&ji;=>>sY{{Gplh?`y$a8 z%6!T_3zx!~$sZ-fnsta4o3Ejn6rYAwFLDM;H+gsfS)1YuH|Y`1dStky(06n`$$H$E zSU%*git(1)$9i-ubiC-aNb{1D8C2_Q#v+i(K*{^)i;=s^}XNuGA@{Ou4VUB0q&(*(fH8SiNef@(-vQxiSB<4SXrud2WDyXwzUO%VC=cKpVLf3O-k2H%=oYDXG`@Y4g7k4*2U~O!? z+%d2j6Bjn%T^Ane-0>m!fNNv6Ue@$mjh6K%`hf3rM#IkN9(7Cjwo_24EJp>2H@W1R zEOl6q^)ir7!zlfqN1)^u*;LjmR%v=;^&5HY?aC31?0&j;XsYYOsHV8~9JN+ww_hmq zf-lECN$~mQcGu3f0VT<~FYzd?(|+BTjv^3(#zwWsLf%FTyB%07db|;*LH0DDJLV*tm+@NyVqn%<%u7i zf(zq3`o0kkujsqccGgE8TVlK~ol+zm+PA!Wrq9pqqb&6dzqMhPg5;5r_0{Wl$~@Qi;ny9S7guz9e|Ku8@uB%)+|Jc=*tYhUd2RtRQII0qOJ}SB zZLpzQf2;l|M)!ooWqN=8YQO0RZNf|6(ew^muUfoEk-xd(#?08YkiA2-II5c+5%+Yd zk>_32VYL^fZ$CO%QOc9s=mA^A^6+!7=dQrr->)tex|E^2(ugw*B!*h?bG7JLp}}b& z#+FldTThm^4lUb2kT$pgOM;EC?U*W|>ImaX0#A2FyMZPix73NHD79~rS-)C3WH4KT zUPyRX)ST2-2519j(-fF@b!Vi-9I*{61*uu1`dd+6 X=d4@LsvDH!{}0%9F06~TTO)o0r7Xn! literal 0 HcmV?d00001 diff --git a/media/img/customercare/twitter-icon.png b/media/img/customercare/twitter-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ab47769c9cf81c2d0e525076cab59471bd8c92cd GIT binary patch literal 10727 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 0 [on_positive will fire when char_rem == 0] + + BY DEFAULT + - maximum characters EQUAL 140 characters + - no events defined + - no class changes defined + - no DOM attributes are created/altered + - user permitted to type past the maximum number of characters limit, resulting in + negative number of characters remaining + + IMPLEMENTATION + + $('#textarea1').NobleCount('#characters_remaining1'); + $('#textfield2').NobleCount('#characters_remaining2', { / * OPTIONS * / }); + + COMPATIBILITY + + Tested in FF3.5, IE7 + With jQuery 1.3.x, 1.4.x + + METHOD(S) + To properly intialize, both the text entry object and the object that will store the + total number of characters remaining must exist and be passed to NobleCount. + + $(TEXT_ENTRY_OBJECT).NobleCount(CHARACTERS_REMAINING_OBJECT); + + Any callback functions assigned to any of the availale events are passed the following + parameters: t_obj, char_area, c_settings, char_rem + + t_obj text entry object + + char_area selection of the characters remaining object + + c_settings result of the options passed into NobleCount at time of + initialization merged with the default options + + ** this is a GREAT way to pass in and remember other state + information that will be needed upon the triggering of + NobleCount events ** + + char_rem integer representation of the total number of characters + remaining resulting from the calculated difference between + the target maximum number of characters and the current + number of characters currently within t_obj + + Both TEXT_ENTRY_OBJECT and CHARACTERS_REMAINING_OBJECT must be specified and valid. + + Upon successful initialization, all appropriate events and classes are applied to + the CHARACTERS_REMAINING_OBJECT, including the storage (if not disabled) visually + or only in the DOM (if enabled) of the integer representing the number of characters + remaining. + + The target maximum number of characters (max_chars) are determined by the following + precedence rules.... + + if max_chars passed via constructor + max_chars = max_chars passed + else if number exists within characters_remaining object and number > 0 + max_chars = number within the text() of characters_remaining object + else use the NobleCount's default max_chars + + CUSTOMIZATION + + NobleCount(c_obj, ) + e.g. $(t_obj).NobleCount(c_obj, {max_chars:100px}); + + + on_negative class (STRING) or FUNCTION that is applied/called + when characters remaining is negative IF DEFINED + + on_positive class (STRING) or FUNCTION that is applied/called + when characters remaining is positive IF DEFINED + + on_update FUNCTION that is called when characters remaining changes + + max_chars target maximum number of characters + + block_negative if TRUE, then all attempts are made to block entering + more than max_characters; not effective against user + pasting in blocks of text that exceed the max_chars value + otherwise, text area will let individual entering the text + to exceed max_chars limit (characters remaining becomes + negative) + + cloak: false, if TRUE, then no visual updates of characters remaining + object (c_obj) will occur; this does not have any effect + on the char_rem value returned via any event callbacks + otherwise, the text within c_obj is constantly updated to + represent the total number of characters remaining until + the max_chars limit has been reached + + in_dom: false if TRUE and cloak is ALSO TRUE, then the number of characters + remaining are stored as the attribute of c_obj + named 'data-noblecount' + + !NOTE: if enabled, due to constant updating of a DOM element + attribute user experience can appear sluggish while + the individual is modifying the text entry object (t_obj) + + + EXAMPLE OPTIONS = + { + on_negative: 'go_red', + on_positive: 'go_green', + max_chars: 25, + on_update: function(t_obj, char_area, c_settings, char_rem){ + if ((char_rem % 10) == 0) { + char_area.css('font-weight', 'bold'); + char_area.css('font-size', '300%'); + } else { + char_area.css('font-weight', 'normal'); + char_area.css('font-size', '100%'); + } + } + }; + + MORE + + For more details about NobleCount, its implementation, usage, and examples, go to: + http://tpgblog.com/noblecount/ + +******************************************************************************************************/ + +(function($) { + + /********************************************************************************** + + FUNCTION + NobleCount + + DESCRIPTION + NobleCount method constructor + + allows for customization of maximum length and related update/length + behaviors + + e.g. $(text_obj).NobleCount(characters_remaining_obj); + + REQUIRED: c_obj + OPTIONAL: options + + **********************************************************************************/ + + $.fn.NobleCount = function(c_obj, options) { + var c_settings; + var mc_passed = false; + + // if c_obj is not specified, then nothing to do here + if (typeof c_obj == 'string') { + // check for new & valid options + c_settings = $.extend({}, $.fn.NobleCount.settings, options); + + // was max_chars passed via options parameter? + if (typeof options != 'undefined') { + mc_passed = ((typeof options.max_chars == 'number') ? true : false); + } + + // process all provided objects + return this.each(function(){ + var $this = $(this); + + // attach events to c_obj + attach_nobility($this, c_obj, c_settings, mc_passed); + }); + } + + return this; + }; + + + /********************************************************************************** + + FUNCTION + NobleCount.settings + + DESCRIPTION + publically accessible data stucture containing the max_chars and + event handling specifications for NobleCount + + can be directly accessed by '$.fn.NobleCount.settings = ... ;' + + **********************************************************************************/ + $.fn.NobleCount.settings = { + + on_negative: null, // class (STRING) or FUNCTION that is applied/called + // when characters remaining is negative + on_positive: null, // class (STRING) or FUNCTION that is applied/called + // when characters remaining is positive + on_update: null, // FUNCTION that is called when characters remaining + // changes + max_chars: 140, // maximum number of characters + block_negative: false, // if true, then all attempts are made to block entering + // more than max_characters + cloak: false, // if true, then no visual updates of characters + // remaining (c_obj) occur + in_dom: false // if true and cloak == true, then number of characters + // remaining are stored as the attribute + // 'data-noblecount' of c_obj + + }; + + + ////////////////////////////////////////////////////////////////////////////////// + + // private functions and settings + + /********************************************************************************** + + FUNCTION + attach_nobility + + DESCRIPTION + performs all initialization routines and display initiation + + assigns both the keyup and keydown events to the target text entry + object; both keyup and keydown are used to provide the smoothest + user experience + + if max_chars_passed via constructor + max_chars = max_chars_passed + else if number exists within counting_object (and number > 0) + max_chars = counting_object.number + else use default max_chars + + PRE + t_obj and c_obj EXIST + c_settings and mc_passed initialized + + POST + maximum number of characters for t_obj calculated and stored in max_char + key events attached to t_obj + + **********************************************************************************/ + + function attach_nobility(t_obj, c_obj, c_settings, mc_passed){ + var max_char = c_settings.max_chars; + var char_area = $(c_obj); + + // first determine if max_char needs adjustment + if (!mc_passed) { + var tmp_num = char_area.text(); + var isPosNumber = (/^[1-9]\d*$/).test(tmp_num); + + if (isPosNumber) { + max_char = tmp_num; + } + } + + // initialize display of characters remaining + // * note: initializing should not trigger on_update + event_internals(t_obj, char_area, c_settings, max_char, true); + + // then attach the events -- seem to work better than keypress + $(t_obj).keydown(function(e) { + event_internals(t_obj, char_area, c_settings, max_char, false); + + // to block text entry, return false + if (check_block_negative(e, t_obj, c_settings, max_char) == false) { + return false; + } + }); + + $(t_obj).keyup(function(e) { + event_internals(t_obj, char_area, c_settings, max_char, false); + + // to block text entry, return false + if (check_block_negative(e, t_obj, c_settings, max_char) == false) { + return false; + } + }); + } + + + /********************************************************************************** + + FUNCTION + check_block_negative + + DESCRIPTION + determines whether or not text entry within t_obj should be prevented + + PRE + e EXISTS + t_obj VALID + c_settings and max_char initialized / calculated + + POST + if t_obj text entry should be prevented FALSE is returned + otherwise TRUE returned + + TODO + improve selection detection and permissible behaviors experience + ALSO + doesnt CURRENTLY block from the pasting of large chunks of text that + exceed max_char + + **********************************************************************************/ + + function check_block_negative(e, t_obj, c_settings, max_char){ + if (c_settings.block_negative) { + var char_code = e.which; + var selected; + + // goofy handling required to work in both IE and FF + if (typeof document.selection != 'undefined') { + selected = (document.selection.createRange().text.length > 0); + } else { + selected = (t_obj[0].selectionStart != t_obj[0].selectionEnd); + } + + //return false if can't write more + if ((!((find_remaining(t_obj, max_char) < 1) && + (char_code > 47 || char_code == 32 || char_code == 0 || char_code == 13) && + !e.ctrlKey && + !e.altKey && + !selected)) == false) { + + // block text entry + return false; + } + } + + // allow text entry + return true; + } + + + /********************************************************************************** + + FUNCTION + find_remaining + + DESCRIPTION + determines of the number of characters permitted (max_char), the number of + characters remaining until that limit has been reached + + PRE + t_obj and max_char EXIST and are VALID + + POST + returns integer of the difference between max_char and total number of + characters within the text entry object (t_obj) + + **********************************************************************************/ + + function find_remaining(t_obj, max_char){ + return max_char - ($(t_obj).val()).length; + } + + + /********************************************************************************** + + FUNCTION + event_internals + + DESCRIPTION + primarily used for the calculation of appropriate behavior resulting from + any event attached to the text entry object (t_obj) + + whenever the char_rem and related display and/or DOM information needs + updating this function is called + + if cloaking is being used, then no visual representation of the characters + remaining, nor attempt by this plugin to change any of its visual + characteristics will occur + + if cloaking and in_dom are both TRUE, then the number of characters + remaining are stored within the HTML 5 compliant attribute of the + character count remaining object (c_obj) labeled 'data-noblecount' + + PRE + c_settings, init_disp initialized + + POST + performs all updates to the DOM visual and otherwise required + performs all relevant function calls + + **********************************************************************************/ + + function event_internals(t_obj, char_area, c_settings, max_char, init_disp) { + var char_rem = find_remaining(t_obj, max_char); + + // is chararacters remaining positive or negative + if (char_rem < 0) { + toggle_states(c_settings.on_negative, c_settings.on_positive, t_obj, char_area, c_settings, char_rem); + } else { + toggle_states(c_settings.on_positive, c_settings.on_negative, t_obj, char_area, c_settings, char_rem); + } + + // determine whether or not to update the text of the char_area (or c_obj) + if (c_settings.cloak) { + // this slows stuff down quite a bit; TODO: implement better method of publically accessible data storage + if (c_settings.in_dom) { + char_area.attr('data-noblecount', char_rem); + } + } else { + // show the numbers of characters remaining + char_area.text(char_rem); + } + + // if event_internals isn't being called for initialization purposes and + // on_update is a properly defined function then call it on this update + if (!init_disp && jQuery.isFunction(c_settings.on_update)) { + c_settings.on_update(t_obj, char_area, c_settings, char_rem); + } + } + + + /********************************************************************************** + + FUNCTION + toggle_states + + DESCRIPTION + performs the toggling operations between the watched positive and negative + characteristics + + first, enables/triggers/executes the toggle_on behavior/class + second, disables the trigger_off class + + PRE + toggle_on, toggle_off + IF DEFINED, + must be a string representation of a VALID class + OR + must be a VALID function + + POST + toggle_on objects have been applied/executed + toggle_off class has been removed (if it is a class) + + **********************************************************************************/ + + function toggle_states(toggle_on, toggle_off, t_obj, char_area, c_settings, char_rem){ + if (toggle_on != null) { + if (typeof toggle_on == 'string') { + char_area.addClass(toggle_on); + } else if (jQuery.isFunction(toggle_on)) { + toggle_on(t_obj, char_area, c_settings, char_rem); + } + } + + if (toggle_off != null) { + if (typeof toggle_off == 'string') { + char_area.removeClass(toggle_off); + } + } + } +})(jQuery); diff --git a/media/js/libs/jqueryui.min.js b/media/js/libs/jqueryui.min.js index c85da15b282..f604e06f0a4 100644 --- a/media/js/libs/jqueryui.min.js +++ b/media/js/libs/jqueryui.min.js @@ -230,4 +230,34 @@ c=this._daylightSavingAdjust(new Date(c,e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(t "dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker= function(a){if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b)); return this.each(function(){typeof a=="string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new L;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.4";window["DP_jQuery_"+y]=d})(jQuery); -; \ No newline at end of file +; +/* + * jQuery UI Accordion 1.8.5 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(c){c.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); +a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var f=d.closest(".ui-accordion-header");a.active=f.length?f:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion",function(g){return a._keydown(g)}).next().attr("role", +"tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(g){a._clickHandler.call(a,g,this);g.preventDefault()})},_createIcons:function(){var a=this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers); +this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabIndex"); +this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); +b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,f=this.headers.index(a.target),g=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:g=this.headers[(f+1)%d];break;case b.LEFT:case b.UP:g=this.headers[(f-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); +a.preventDefault()}if(g){c(a.target).attr("tabIndex",-1);c(g).attr("tabIndex",0);g.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ +c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; +if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected); +a.next().addClass("ui-accordion-content-active")}h=a.next();f=this.active.next();g={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):h,oldContent:f};d=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(h,f,g,b,d)}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +this.active.next().addClass("ui-accordion-content-active");var f=this.active.next(),g={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:f},h=this.active=c([]);this._toggle(h,f,g)}},_toggle:function(a,b,d,f,g){var h=this,e=h.options;h.toShow=a;h.toHide=b;h.data=d;var j=function(){if(h)return h._completed.apply(h,arguments)};h._trigger("changestart",null,h.data);h.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&f?{toShow:c([]),toHide:b,complete:j, +down:g,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:g,autoHeight:e.autoHeight||e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;f=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!f[k]&&!c.easing[k])k="slide";f[k]||(f[k]=function(l){this.slide(l,{easing:k,duration:i||700})}); +f[k](d)}else{if(e.collapsible&&f)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.5",animations:{slide:function(a, +b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),f=0,g={},h={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){h[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/);g[i]={value:j[1], +unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(h,{step:function(j,i){if(i.prop=="height")f=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=f*g[i.prop].value+g[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide",paddingTop:"hide", +paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); diff --git a/migrations/44-cannedresponses-initialdata.sql b/migrations/44-cannedresponses-initialdata.sql index b1af0f4eaab..6c2f807fc2a 100644 --- a/migrations/44-cannedresponses-initialdata.sql +++ b/migrations/44-cannedresponses-initialdata.sql @@ -1,31 +1,31 @@ INSERT INTO `customercare_cannedcategory` (`id`, `title`, `weight`) VALUES -(1, 'Welcome and Thanks', 0), -(2, 'Using Firefox', 1), -(3, 'Firefox Beta', 2), -(4, 'Support', 3), -(5, 'Get Involved', 4); +(1, "Welcome and Thanks", 0), +(2, "Using Firefox", 1), +(3, "Firefox Beta", 2), +(4, "Support", 3), +(5, "Get Involved", 4); INSERT INTO `customercare_cannedresponse` (`id`, `title`, `response`) VALUES -(1, 'Welcome to our community', 'Thanks for joining Mozilla! You're now part of our global community. We're here if you need help: http://mzl.la/bMDof6'), -(2, 'Thanks for using Firefox', 'Thanks for using Firefox! You’re not just a user to us, but part of a community that''s 400M strong: http://mzl.la/9whtWo'), -(3, 'We’re a non-profit organization', 'Hey, I’m a Mozilla volunteer. Did you know Mozilla is made up of 1000s of us worldwide? More here: http://mzl.la/cvlwvd'), -(4, 'Tip & tricks', 'Need help getting started with Firefox? Here are some tips & tricks for getting the most out of it: http://mzl.la/c0B9P2'), -(5, 'Customize Firefox with add-ons', 'Have you tried add-ons? Cool apps for shopping, music, news, whatever you do online. Start here: http://mzl.la/blOuoD'), -(6, 'Add-on reviews', 'Just getting started with Firefox? Add-ons personalize it with cool features & function. User reviews: http://mzl.la/cGypVI'), -(7, 'Upgrade Firefox', 'Hey, maybe you need to upgrade Firefox? New version is speedier with a lot more going on. Download: http://mzl.la/9wJe30'), -(8, 'Update plugins and add-ons', 'Have you updated your plug-ins and add-ons? Should work out the kinks. Here’s the place to refresh: http://mzl.la/cGCg12'), -(9, 'Try the Beta', 'Try the future of Firefox! We need your help testing the new beta. Hop on board: http://mzl.la/d23n7a'), -(10, 'Firefox Sync', 'Tried Firefox Sync? It’s awesome! Switch computers & it saves open tabs, pwords, history. Try it: http://mzl.la/aHHUYA'), -(11, 'Firefox Panorama', 'Heard about Firefox Panorama? It groups and displays your tabs, eliminating clutter. Give it a whirl! http://mzl.la/d21MyY'), -(12, 'Fix crashes', 'Sorry your Firefox is crashing. Here’s a list of quick fixes to prevent that from happening again: http://mzl.la/atSsFt'), -(13, 'Slow Firefox startup', 'Slow start could mean your Firefox just needs a refresh. Here are tips to make Firefox load faster: http://mzl.la/9bB1FY'), -(14, 'Quick Firefox fixes', 'Have you tried Firefox support? If their quick fixes don’t solve it, volunteers are ready to help out: http://mzl.la/9V9uWd'), -(15, 'Ask SUMO', 'Maybe ask SUMO about this issue? Firefox’s community support team. They’ll know what’s up: http://mzl.la/bMDof6'), -(16, 'Get involved with Mozilla', 'Want a better web? Join the Mozilla movement. There is something to do for everyone. Get started: http://mzl.la/cufJmX'), -(17, 'Join Drumbeat', 'Want to spark a movement? Mozilla Drumbeat is your chance to keep the web open and free. More info: http://mzl.la/aIXCLA'), -(18, 'Become a beta tester', 'Become a beta tester! Help develop the next Firefox. You don’t have to be a techie to contribute: http://mzl.la/d23n7a'), -(19, 'Mozilla Developer Network', 'Open up the web & make it better! Build web pages, apps and add-ons here: Mozilla Developer Network http://mzl.la/9gQfrn'), -(20, 'Report a bug', 'Thanks for finding a bug. It makes everyone’s Firefox experience better if you report it. It''s easy: http://mzl.la/bcujVc'); +(1, "Welcome to our community", "Thanks for joining Mozilla! You're now part of our global community. We're here if you need help: http://mzl.la/bMDof6r"), +(2, "Thanks for using Firefox", "Thanks for using Firefox! You're not just a user to us, but part of a community that's 400M strong: http://mzl.la/9whtWor"), +(3, "We're a non-profit organization", "Hey, I'm a Mozilla volunteer. Did you know Mozilla is made up of 1000s of us worldwide? More here: http://mzl.la/cvlwvd"), +(4, "Tip & tricks", "Need help getting started with Firefox? Here are some tips & tricks for getting the most out of it: http://mzl.la/c0B9P2"), +(5, "Customize Firefox with add-ons", "Have you tried add-ons? Cool apps for shopping, music, news, whatever you do online. Start here: http://mzl.la/blOuoD"), +(6, "Add-on reviews", "Just getting started with Firefox? Add-ons personalize it with cool features & function. User reviews: http://mzl.la/cGypVI"), +(7, "Upgrade Firefox", "Hey, maybe you need to upgrade Firefox? New version is speedier with a lot more going on. Download: http://mzl.la/9wJe30"), +(8, "Update plugins and add-ons", "Have you updated your plug-ins and add-ons? Should work out the kinks. Here's the place to refresh: http://mzl.la/cGCg12"), +(9, "Try the Beta", "Try the future of Firefox! We need your help testing the new beta. Hop on board: http://mzl.la/d23n7a"), +(10, "Firefox Sync", "Tried Firefox Sync? It's awesome! Switch computers & it saves open tabs, pwords, history. Try it: http://mzl.la/aHHUYA"), +(11, "Firefox Panorama", "Heard about Firefox Panorama? It groups and displays your tabs, eliminating clutter. Give it a whirl! http://mzl.la/d21MyY"), +(12, "Fix crashes", "Sorry your Firefox is crashing. Here's a list of quick fixes to prevent that from happening again: http://mzl.la/atSsFt"), +(13, "Slow Firefox startup", "Slow start could mean your Firefox just needs a refresh. Here are tips to make Firefox load faster: http://mzl.la/9bB1FY"), +(14, "Quick Firefox fixes", "Have you tried Firefox support? If their quick fixes don't solve it, volunteers are ready to help out: http://mzl.la/9V9uWd"), +(15, "Ask SUMO", "Maybe ask SUMO about this issue? Firefox's community support team. They'll know what's up: http://mzl.la/bMDof6"), +(16, "Get involved with Mozilla", "Want a better web? Join the Mozilla movement. There is something to do for everyone. Get started: http://mzl.la/cufJmX"), +(17, "Join Drumbeat", "Want to spark a movement? Mozilla Drumbeat is your chance to keep the web open and free. More info: http://mzl.la/aIXCLA"), +(18, "Become a beta tester", "Become a beta tester! Help develop the next Firefox. You don't have to be a techie to contribute: http://mzl.la/d23n7a"), +(19, "Mozilla Developer Network", "Open up the web & make it better! Build web pages, apps and add-ons here: Mozilla Developer Network http://mzl.la/9gQfrn"), +(20, "Report a bug", "Thanks for finding a bug. It makes everyone's Firefox experience better if you report it. It''s easy: http://mzl.la/bcujVc"); INSERT INTO `customercare_categorymembership` (`id`, `category_id`, `response_id`, `weight`) VALUES (1, 1, 1, 0), diff --git a/requirements/prod.txt b/requirements/prod.txt index f42d2a403c1..a4f5676294f 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -22,3 +22,5 @@ pytz -e git://github.com/jsocol/commonware.git#egg=commonware -e git://github.com/pcraciunoiu/py-wikimarkup.git#egg=py-wikimarkup -e hg+http://bitbucket.org/danfairs/django-authority#egg=django_authority + +-e git://github.com/joshthecoder/tweepy.git#egg=tweepy diff --git a/settings.py b/settings.py index 04c301ca502..3ad289be6db 100644 --- a/settings.py +++ b/settings.py @@ -291,6 +291,11 @@ def JINJA_CONFIG(): 'ie': ( 'css/ie.css', ), + 'customercare': ( + 'css/jqueryui/jquery.ui.core.css', + 'css/jqueryui/jquery.ui.theme.css', + 'css/customercare.css', + ), }, 'js': { 'common': ( @@ -322,6 +327,12 @@ def JINJA_CONFIG(): ), 'gallery': ( ), + 'customercare': ( + 'js/libs/jqueryui.min.js', + 'js/libs/jquery.NobleCount.js', + 'js/libs/jquery.cookie.js', + 'js/customercare.js', + ), }, } @@ -426,3 +437,6 @@ def JINJA_CONFIG(): # Customare care tweet collection settings CC_MAX_TWEETS = 500 # Max. no. of tweets in DB CC_TWEETS_PERPAGE = 100 # How many tweets to collect in one go. Max: 100. + +TWITTER_CONSUMER_KEY = '' +TWITTER_CONSUMER_SECRET = '' diff --git a/urls.py b/urls.py index 406ec5228c0..0872a4e6cc1 100644 --- a/urls.py +++ b/urls.py @@ -19,7 +19,7 @@ (r'^upload', include('upload.urls')), (r'^kb', include('wiki.urls')), (r'^gallery', include('gallery.urls')), - (r'^customercare', include('customercare.urls')), + (r'^army-of-awesome', include('customercare.urls')), # Kitsune admin (not Django admin). (r'^admin/', include('kadmin.urls')),