From c3568101a3fbfa382dc72cacfd493e1ab271e18f Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Tue, 3 Feb 2026 04:38:54 +0000 Subject: [PATCH] Autosave: 20260203-043854 --- core/__pycache__/admin.cpython-311.pyc | Bin 116791 -> 116854 bytes core/__pycache__/forms.cpython-311.pyc | Bin 29099 -> 31057 bytes core/__pycache__/models.cpython-311.pyc | Bin 29939 -> 32646 bytes core/__pycache__/urls.cpython-311.pyc | Bin 5895 -> 6501 bytes core/__pycache__/views.cpython-311.pyc | Bin 85168 -> 91994 bytes core/admin.py | 1 + core/forms.py | 30 +++- ...lunteer_is_default_caller_scheduledcall.py | 32 ++++ .../0041_alter_volunteer_options.py | 17 ++ ...fault_caller_scheduledcall.cpython-311.pyc | Bin 0 -> 2306 bytes ...41_alter_volunteer_options.cpython-311.pyc | Bin 0 -> 764 bytes core/models.py | 44 ++++- core/templates/base.html | 5 +- core/templates/core/call_queue.html | 158 ++++++++++++++++++ core/templates/core/volunteer_detail.html | 21 ++- core/templates/core/volunteer_list.html | 27 ++- .../templates/core/voter_advanced_search.html | 116 ++++++++++++- core/templates/core/voter_detail.html | 57 ++++++- core/templates/core/voter_list.html | 63 ++++++- core/urls.py | 7 + core/views.py | 147 +++++++++++++++- 21 files changed, 678 insertions(+), 47 deletions(-) create mode 100644 core/migrations/0040_volunteer_is_default_caller_scheduledcall.py create mode 100644 core/migrations/0041_alter_volunteer_options.py create mode 100644 core/migrations/__pycache__/0040_volunteer_is_default_caller_scheduledcall.cpython-311.pyc create mode 100644 core/migrations/__pycache__/0041_alter_volunteer_options.cpython-311.pyc create mode 100644 core/templates/core/call_queue.html diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index 79533be5a006940d0b628015ef7f6ed06dca2228..82d9cc3dc0f72f659d757c1447b9801fd6422669 100644 GIT binary patch delta 1477 zcmZ{kdrVVT9LM`T#oHI9MX6L?0dzoNu7m}VjXCOj%QQHr(=s0&w*mrfy->l8EQ+Wk zi^z6~Cz}u)GDc0a#5Cb9TUboomL{fo zH%YW~>b$ltT^qdiojR9Q4n&GgE+&E87L%uz0 zldC3d<^`G{D02P8(`*59&l660bmBmc78g)MTzctW@_INR{jMd7t@);u;fq+~WUT{> zv8g*Z85ZT?UwqKZ#=C1V9`oG&#LDzcK62D)22)cI#^lVow-^`|;{99TiOtTnFxH(Q z-;Y+rM&{d=u1Y3f2Vn_S3KGr|(n&`uLEsy$sB{|0=>QGvP%$s;4z~EEY{{tfSs?=! zrPziyfm9x~V#IC#1}W?G|PI}!=PQ$+d_K7gr!QxRxD@CDNt9H(2IC#1@e`F8n}TXenZ3_ zB=Z74O5otteiT4ZI{nxUp(Plp4@^nE2VRAj|JH#bLp8a)#mViwwJw|?c{?e(Uze# zpq18sjP@$wk-b{esdf{|%E42Zg^+5{>6$y_ndn-j_YAJ2B2U>opf-jT8u+A$3@%^9 zc8iwKO$8nN-bFYq0@)>m6^iWxltKuqiKJTU)k@wph<2f!2G;TigZLR${M$=-8QnZ@ z2!ET-(abYyF!vl*D{S}>*YFNE45JD@zGoO~@H{^^jIxAE@|kQzw({#R*2BJ$3SOdh zZ6NCyKN3)n$Nmw7u!Y|kK`*v*F@iGn@#%|TwIe`YVY(6D5xyr>@mmpW5=3?CjeP#` zAoA7pJ1%3Vor&@NI7m?h6aV^C4B?>C^cgN9%}nFzgjIw&%H|;}$n(e0_nh{8Xjfai zOxg+6_Ey^|Eo+pt4-ooQ%o{73f?~MQzfS5N{T!zaFYIUVU|RS8ze$H{q;#t2*_pV{ ZpYh*}UdPg>kT%WYk(Eo78(*T1{Rh%DlcfLv delta 1479 zcmZ`(ZA@EL7{1S;+|rKH@=+)s1u7e?j@7U5QJoGD$DG@k!%ZwMmC!<&4n_wKTtYfN zwj~pTyE8}4mf=7KWJH!GyC!pshJ-&8g31!z%;I94F2)3$4zi)~yq7pL65Hgt=f3B8 z-}kxCd+xo{t5qqC6&_u}kvA9Fbb#F;_^=Xyw@Oqv5IH09a;(+Sd&? zl%}&I$PTBCPQ>e75t6j;ih;lDMqPN@7hWSQN?%5bGIM!H!hle-5R(4={}8`Dv^iYz zr46x*kfh*W1h)kzxCmt~+p2^n(~b8iNN`>mntX!YgEF?tru;eSb!a&ag6@n6{!Og= zf#C02k#NgY9+SsOkfJz7^TRi%bFEkm$KU*lVNv<%mufJj>{cNzheNkMHG%OaJCcnO z6SW9FQ(m2KXA+~1{QEK#hw~Pi8SBw0_R)3WpYOKDt+Ws~fgqAvHWKs@q>`W{f=J$J zLXk}-l9vK63b-rpY;5)iGlP2dnh6SER2$7W03`BXEy%)qsyPYH;wAN{8$Bj*tBJM~m7tWbE5jjXzi(utMHAgjqFV@J z)vAq1WGqS6G=8!Pu4H7Z*K6G6(0IRtxfL(Z#za7BmIKa2mV-fH3O}lXeAMo7QF^><` zm2cpv4o~y3y{M9%qT^dRJhmP=$W+};xM+cM=@E125edvZr9;dmhbafs-TX=iUdAhY zZ70^~Jw&Nu+Ib$!F!J_JBp53xNWl0BL1L9m$;`Cz8=YuP)2!J~uC&o8bq|cPrAzn> zi+ZXXcOWO~#nJ8%N4rq{<}l7BVU^l_N?696dT#b3jep&TtuC#gi#lotRr74eGUI6X zF#?;q^&{j#ZV;t|wPaxypAMju&z?r1e1M__+|`dCQO@HAupK?zKY#_pJGA2#6?ka3 zXx#BJ#?i|+3}PEz<9rbLc!p06qCmHvIOaXVN#_}q!1640?We~rp;a3nYrsSNeP`{lPgUV2QM^Irw&C;N} zltmE5^%pPzuX^?Z`jBFvcnU!l!8}zfqE!R0y@(ST+Sf<>AZV|kcBHkTYZLTx$0gX& yqprV%L;B};F%)A~`v1$c)j5(rPD1lT{`3Vy!; diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc index 1bb1da0b3a87929bcf454410288e23a58a427cd7..ef9dbe1583e9f69aa7fbc4728d1753044d7e00d9 100644 GIT binary patch delta 7156 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 delta 5995 zcmc&&dvKK172j`@-OXn6+K~5iAqlXM1Ox;`5*{IeAZ&nyAds>y*$=Z}vx|4XjS|sd zrPW$!3s)`10{LZ)8Y?3um z{G&|f$35rVd(S}iB}>bQE@!%m=?bDN znXYEKis)*lT}-=(o(Vd4CeyQst{FYkEN0abt8SE4!>rlFniFTqf0(V7xx{euwskyV z9?|oOt|<4{cbeP{m*H-=qFeTb#X#h;0xCy7pY~gMyu2tjlKwYyVHxp6Jzy4~2Czsz zVjEG4JNA7E8+=qTLt3BM2sR9!V52)z+yd?Vhwwg8p_wi384VjIStfG$9{sf3UXv=Hs0e}@etH^r_NeM`xQf$pkg z=g5akYL*sbF)cL-H-YYG=?e#X)wX~d^oxUFR{*L3GXe7e^X0!wD%T@Mde+)-IH>wU z#)<|=8^O=*+`eT?$F?qS%Z85jmex)-UU%+Xvu&NXvwgiM!Cxr1mR8hp(Afz)vBfTe zk#aswEC=5UxRHQ@iKRT-Lt&YaMOMg~0L`+ovc$Ru!?iLyRHA%cs+ECw zw#VM6{HuBR7zuTIAma7)YJovj;EduZ-~j+93Ub6qi*H~A-R``kWUv!Mw}toi)5VC; znFB$Mtm72PxFf2HgAr8|PAnY)aHhobqnlP{1VRzb7wT0Fhh#)Fu}=#OsJac8DBugy zMd1{}S;yrOk(@@b7-=+?NB7P=q}1|7xfP2h2I&ZxfE{wd+CsUwCS*9}2*=7&d;b=W zjdeiP`oezQ>Kh1C%nYxyhY$vj+dk3tHtcJ-9wWXEt1vR$|G0d=_LeL@7OuKS9F?x- z(wMLAZe{q}nD%|Zc%Qo+NuI{bB8~%20N`RF0h1g{yhlk8ndBN`4i&BohkQu5HcGEX zE>?2)oR_C?*hwe>1leIdbK?#>$qs9D-(NN%2{W)Do`lG}C*?og^Cp|Vc;4%A(|?2o z<4qSoCf+#v9hmgx?XTz#Q-*E|>{o+#3YkPSdIIu_j6ji0{7c~AJR{RVwDZSfn{M0-gBhiRi zaJexD{8N~nR9Wvl+%$h%iID-X)wtgIO3 zSE>?ReyYY=4K6HP*il{dbkxAH%I{7$%Fhc}`Fp^F1RlB`6K)=-N{Sk!+q-DPc1P$y zR1-;W!tdn4rpL#nY0TB^F&hQxMJPH8m?AlIAWxB;dUp5dTepo~-Y=G>u}iDxPUZ14 zPT{unBX=&11L)1_S7Zka*Z-!jcdWajCk?iEa$X8ljtKcF%%@+(B*TCKu z2*%r&3nVcbtCT&(If&26#!2FaaOkGLVBYHhzP)c?v^_YnE@2MfZ4Abaaw*}6cea$LKF)MuShlTxI!C+%rGWRwYkw!9eRF5w^=W^s zYxZ>7**}2)j@N#fwC|B!+wb3J6~z#h0OkT}0gDKz$%UuYh!!#0?B$T$1o(_*&I#Fs zLYh=J-;;svN?X?jC;sHI?%HuR6pfwq)iuk49gkRQ?y(%Q$c5GO&S%|y|{c~kKI;GMK|)C;qxnd9-YFyS799>pWXYS zH{PaQ<@<2rwm{Ycn1S2k5g)MwKB2LT98fBoeA$zo5caJz5A&j5Vx^IY7;PkQ=O(?E zzXJEy0Pf737^U*b^AHRHIsi)nTM1Gprk*tzu8)5odjtMyo3ko;@wOuS=+7;+v3vYQ zQ}wkULpz|F9d=%gJM7~``TAgA$@P`5)qS;1ODJ;F)o%rJ01Gh~tKUlOiM~ga5({zN z=4&~f2g3VRmlk#n;!{OfrKi8lZ^IJAWXQf(3pMoislEHTdg-=~sMZ@EP~B<9?>y}5 zD6DMs+jipQOw-0si>J-1_fS4+p{*2K>z{55Afe<0k+zogL*2gcFGA#A$_fO;*4 z0b2<4+&g_CE#f`s6Mk<}`i~@^`C!lnMJ)2hm9Nzx{39USO diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 2a861dd4b6d1836e8863aaba9cca4cbb63e8c55f..9a15037c6fb6f5653a1783d591777a10383527bc 100644 GIT binary patch delta 4610 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 delta 2665 zcmZuyeNa@_6@T~b7c9$yy1=p^tcf6tK+-4`Bp@jtQGuXfglrI8_C59CetF-5fq;`Wco+H>y0##-O* z`|Z8={LcB^k8|$6c!w?inc07oo^F-!xpa73d%F3!-N|}?wr-EXtgueWQyx2K*i^(k zaINHZb}lyQ`3XyVYShTPMh&A+-p+?j!XsdsUc z?F4tse76e5N-8eJB7YH;VxZjsFVr=8lB~qMmg7$tM=iRnm~bUVo`;@kuvmA9&4Ie5 zZsjkLrOOCzH+SI={~Uh4;-I&Sa*k`DzDIeL+U*C^-rMsv4`RO z&XU+WkNt}=H@w~OmgV2%^dAWZ8!Nhn#9wJ3Ie~augll1r6Z2s#noZp74-bZ-!*N@q z>eqt4K(nR>l*FX2lCP6U*2sZyNbQRbM^t_TZZ}>qUnAQBTx@c&Td^xmrwpzNQ}MiX zAK1&_^=&z^*=?s7ZctlGdto6%UlT$+T@B!ZwQ#6Up$R=iLEUh^Wt}yjI0O&EUs}E; z=QFsF=ajh&)2muzS6d6@6vc5=^178QaI~*wXP~Qq zqt)<)XAL~3xuCwlX%Wi240d*I$SNllPO3)POE9P#RK*mdOeATwiYN~1&5T%c1NipEZ zIBPnMRXanKD;{r}EFmjdNQzl8%vzwhtuRltPGb(vP#z}OcEQd77R(;^X5QnPLaz5X ztPq@)%K_9?I0-hJdK#-_CRr(7$33hp#j2#u+U{Xx3s%ljtj)Nh+4R%6+8KNkkJmXV z?PH4lXo@#i$-r}SO-j!&ZysKBneo)!;Q*$fs&aUxTbKDMm{uK@4D?(KNN}>I$|y@w z6U^_(Wd^A5I>&ht+B{gB_#^U@Q$cX55*+nV`|kvc1h)`$BZAxQo=B9eC?|VTRg}~Y zI=@P!{c}S4GOOf_W7hRq*2YU&8z+rZ*2^i5mrchkQ)v@!<+PakvLMkF$!GaX8EA($de)979eFy^&<%k~jXzKD62T+^ zw2n*4(31}_6lpvS7E(9H4sXnpPN*W|+B0~uRt`9%p+~t6_ zbUS>1&ztbdKz6Qys`ox%g{j^L;7qSgt`unupZ5NgRl$+Izp*_K+S^$q6n4-Ann_C( z#N*WZs;ss$m|l}(t)fwaZm{@H%2f<9vYqg*?>Z}nv;AE;jbv}3NUaDS0~hziiJ|t)0iUB23Cr3>akmO(Csb(;HVkcAcePL!TP!XpvBe!E z?Y+fnwI6LS5@{>kXm`Q; z0VVy{7;|~={jedpjU9ur;Ndhe6O{!0a3@${?IAaUQP>oEm-WOt^B&oTf0w1-L%+V|D^w zJ-j)qj>HPcE>6FJT2{Dr_@q@M3&FQz-+5*?OQEJ`9Up=l!z%jyOWGd193s+!|SJeI6s@SJFK(_p=T1#(tSq z&P(^l$>yon1!22+H)AWD7%ShK!#2!I{|^Zt9KZRM@sSm*h0RO%$7%C-Z41J7^KM2l N6dhS)1<*EL{a*>Jlve-% diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 254fb7029a072e17713dbcdcbe50d346bd5d1fac..f61391bdc4c183551732cc258768a9f89cab1279 100644 GIT binary patch delta 1593 zcmZ{kO-vg{7>2#%vrR(57;FMK{G^E?sNK@Ap3M%y?&J z{jBS+-l|uXmFFz{nwd^Ev4|)U@S7K#<@4O?%t=^Ks ztyN*gxz%@KC4{AO>)MI6#;wjIxBMs8`WxHJGZxEhewVI&<$ix6HD~F3@b@jl7LG zo2;s%jMIw8C*SDm;jed1`a(ASjRE)WsUs!4D01nLjceJKt zV%AJFQ);BB@pOq5NoAOp#e--xyF@$^sLKH%5 zUM3dIF>@^n$OriD8_;IE8VxCv7&vg#!7yIh!jL79 zrI2MQnRr-AJa5jsX~X4W69%=4fJ#ASn=I?CngDDcxU zL|}-*5Zjh~$DCRo@X@0d42uL7DJ-(DWZR@A E1yzgy-2eap delta 929 zcmZ|OOHUI~6bEoxPFpH3g%hMip)tzjWC@e3#+_a=AYPK|LV=6(Sa@4YZfXEG+CPr?O&XmDDuwlel+EDx)yX$QnQQAm8RkmZvf4n`is`8 zu9WuiNgcn|{ut1gs?I5;QvVf7HY3@pth$xTJ;vZ6;Gy7Q#k}=hw6M87uhPyzoS4Rt zB9NkxVg}x2#v+56kJ`7R)Y6pi$Dj~UC@9RNpt0(Doq`_7x?Sz&ekbdJtcS9eS=@4u z4Xs!lM!Q()Krc9*f_3OEr%UiOI znX^;ShqgHVf&uh~vq$hO+P8W(f`WbjdzbT~+b_G=+^`d*jlsPU48sJ5DGaj1rJtqtavA_O60~`l2{Fiy=)QO(D(3W#Z~lA}b%S1NRJJ zh!BWSh_DG6nABD{a#32>U0B5sBM_qyW2y{X(*oXnkhTxtxcCx$$DhJ=8JW@|zCtq% z#PR3?h75rWg$%nP6VvE(t<#i}oq!V`LPnmkmx0lppanqWn@K*)bChnLoW_bVo(XF6jZh<5}T#se5mlh>L1A+Aua#_ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index f3fd53ff3bfe18b4e8667bee88d7f0d25919c515..2acb99de2f5259e746e4d755972a2d2dc3c126e6 100644 GIT binary patch delta 19225 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 KNFEiCjrwqGC{oNzM=kCo^Hs1SJBAk9MgA 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 diff --git a/core/admin.py b/core/admin.py index 22fa994..58dc59c 100644 --- a/core/admin.py +++ b/core/admin.py @@ -790,6 +790,7 @@ class EventAdmin(BaseImportAdminMixin, admin.ModelAdmin): @admin.register(Volunteer) class VolunteerAdmin(BaseImportAdminMixin, admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email', 'phone', 'tenant', 'user') + ordering = ("last_name", "first_name") list_filter = ('tenant',) fields = ('tenant', 'user', 'first_name', 'last_name', 'email', 'phone', 'notes', 'interests') search_fields = ('first_name', 'last_name', 'email', 'phone') diff --git a/core/forms.py b/core/forms.py index 4705bbf..1b46fd8 100644 --- a/core/forms.py +++ b/core/forms.py @@ -1,5 +1,5 @@ from django import forms -from .models import Voter, Interaction, Donation, VoterLikelihood, InteractionType, DonationMethod, ElectionType, Event, EventParticipation, EventType, Tenant, ParticipationStatus, Volunteer, VolunteerEvent +from .models import Voter, Interaction, Donation, VoterLikelihood, InteractionType, DonationMethod, ElectionType, Event, EventParticipation, EventType, Tenant, ParticipationStatus, Volunteer, VolunteerEvent, VolunteerRole, ScheduledCall class VoterForm(forms.ModelForm): class Meta: @@ -256,7 +256,7 @@ class VolunteerImportForm(forms.Form): class VolunteerForm(forms.ModelForm): class Meta: model = Volunteer - fields = ['first_name', 'last_name', 'email', 'phone', 'notes', 'interests'] + fields = ['first_name', 'last_name', 'email', 'phone', 'is_default_caller', 'notes', 'interests'] widgets = {'notes': forms.Textarea(attrs={'rows': 3})} def __init__(self, *args, tenant=None, **kwargs): @@ -265,10 +265,11 @@ class VolunteerForm(forms.ModelForm): from .models import Interest self.fields['interests'].queryset = Interest.objects.filter(tenant=tenant) for field in self.fields.values(): - field.widget.attrs.update({'class': 'form-control'}) + if not isinstance(field.widget, forms.CheckboxInput): + field.widget.attrs.update({'class': 'form-control'}) + else: + field.widget.attrs.update({'class': 'form-check-input'}) - # self.fields['interests'].widget = forms.SelectMultiple() - # Re-apply class for checkbox self.fields['interests'].widget.attrs.update({'class': 'form-select tom-select'}) class VolunteerEventForm(forms.ModelForm): @@ -336,3 +337,22 @@ class DoorVisitLogForm(forms.Form): widget=forms.Select(attrs={"class": "form-select"}), label="Candidate Support" ) + +class ScheduledCallForm(forms.ModelForm): + class Meta: + model = ScheduledCall + fields = ['volunteer', 'comments'] + widgets = { + 'comments': forms.Textarea(attrs={'rows': 3}), + } + + def __init__(self, *args, tenant=None, **kwargs): + super().__init__(*args, **kwargs) + if tenant: + self.fields['volunteer'].queryset = Volunteer.objects.filter(tenant=tenant) + default_caller = Volunteer.objects.filter(tenant=tenant, is_default_caller=True).first() + if default_caller: + self.initial['volunteer'] = default_caller + for field in self.fields.values(): + field.widget.attrs.update({'class': 'form-control'}) + self.fields['volunteer'].widget.attrs.update({'class': 'form-select'}) diff --git a/core/migrations/0040_volunteer_is_default_caller_scheduledcall.py b/core/migrations/0040_volunteer_is_default_caller_scheduledcall.py new file mode 100644 index 0000000..4e41184 --- /dev/null +++ b/core/migrations/0040_volunteer_is_default_caller_scheduledcall.py @@ -0,0 +1,32 @@ +# Generated by Django 5.2.7 on 2026-02-03 01:13 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0039_alter_tenantuserrole_role'), + ] + + operations = [ + migrations.AddField( + model_name='volunteer', + name='is_default_caller', + field=models.BooleanField(default=False), + ), + migrations.CreateModel( + name='ScheduledCall', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('comments', models.TextField(blank=True)), + ('status', models.CharField(choices=[('pending', 'Pending'), ('completed', 'Completed'), ('cancelled', 'Cancelled')], default='pending', max_length=20)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('tenant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_calls', to='core.tenant')), + ('volunteer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='assigned_calls', to='core.volunteer')), + ('voter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_calls', to='core.voter')), + ], + ), + ] diff --git a/core/migrations/0041_alter_volunteer_options.py b/core/migrations/0041_alter_volunteer_options.py new file mode 100644 index 0000000..ffe8c4d --- /dev/null +++ b/core/migrations/0041_alter_volunteer_options.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.7 on 2026-02-03 03:43 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0040_volunteer_is_default_caller_scheduledcall'), + ] + + operations = [ + migrations.AlterModelOptions( + name='volunteer', + options={'ordering': ('last_name', 'first_name')}, + ), + ] diff --git a/core/migrations/__pycache__/0040_volunteer_is_default_caller_scheduledcall.cpython-311.pyc b/core/migrations/__pycache__/0040_volunteer_is_default_caller_scheduledcall.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9dee99eab30ebd123caf107523911fa153cb034b GIT binary patch literal 2306 zcmah~O>7fK6rNq%Yp-Jm+k~2s9|Hn}3B*y82BobkB@RYF_=%DhRAyYB8f zB#~NCsfQl9HRm4ER`?KAJ#g%?$BneAtm&mvPuz^iiBsRqdJU!s~IXwO-N3gJl@{yNpdM_{1ctfjNs-u~PO{Ip3iEdYVy8M;tOd^oIhue{T0sO<`kG6C?9*z(TR&f-^ID*`l$XLc<9B&Wp zhXDs3e{704!8Li-m<-G9Sdy?xW0$sox8NfR= zp!3myPL}H=0~|73KN0YCsn4bQTsq+JX*}9KGZ2?}91rp#e-JaM8p30EygjiG-SE8M z5wO?ESm&YetnuANUN&WH4#! zg!zz*0n6p8Q6aDuCJ$I^6cYDx1PJUYTB(^@h1eGBT-c$yt?0z4IyD;aMXjg~1mbVR zFrO$Y#x&k)VzwiHEygzqYgF=6Oi$QBLU<G%BBISW&zWLMRX3u6Dm3; z9ae2ys~UjLs$lO9bK8EM@)0Y`VhtNDUAHa+Yvmca!i1466DqwM@0kFf7cF)`sKiTU z-^-8Cn8FjSC^W7pP*W%z@Cilvx~1wY3^v1r<(U{24U)qyH5yyQxWwvhvAcmLmP}|M z)!-sJROB_j%Q^&>wCW-h-d~c}$+pvDi#65q+2k_pdR=P}e;O}Af?(Hopfe;~SB+gT~fwtSk4vTv?%Uvq^e4>aXZE1clzHg__wQh1Lc%b*n(O zNd@At3QtVyvE5WFq`)#$czY8UW@hGQlzwuRfis}=OUbG+-Q2O*&B6)0eC@yC!hPER zbtNRvc0=Nb^mL^gNAma&aW6L3$)4||FLW{&pI!1Y7k?pcX6`UE=Vj))(XbqUg@7C} z!Yp#kVzQGy`%n6mo4xXE%gbJQ5&rXnTUK1dagGEOFV@}M(qV4N%PqO7B6oU~IlX$Y_4|%@{ib*Qfp`6p zTipi8Z-qPD*9!NwA~IhqOp?9}zQ*0j!rrDgSvbJpZS|qITJ}~|Z?*2N+MrVu*O=-f zvBq9GjbQ)<44@374j8B1GgEt)yfae=o4;$`e94=?@6A7SH=lsQH^MEZH+Gv@0tHK; z%o3tX%Ok_xNP^V?$PpvmBpgXP4K#j`%b$(*_ zIq}2mQc|-N~%=M`s^bT%-Z9b-M8~*p8Rcj*#okl$;apu1Ndc<#@cmo z@tA@m5Fl6#6EoNCkN$lPs(u z)n`GoMd=YB44DAB%tmZzTY#-`gCI&_i&n&bw2z7OWI;?wM>s^bq}`o{rDy3@C>84d zVDM krOg Voters + @@ -76,4 +79,4 @@ {% block extra_js %}{% endblock %} - + \ No newline at end of file diff --git a/core/templates/core/call_queue.html b/core/templates/core/call_queue.html new file mode 100644 index 0000000..d28c9fb --- /dev/null +++ b/core/templates/core/call_queue.html @@ -0,0 +1,158 @@ +{% extends "base.html" %} + +{% block content %} +
+
+

Call Queue

+
+ {{ calls.paginator.count }} Pending Calls +
+
+ +
+
+ + + + + + + + + + + + + {% for call in calls %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
VoterPhoneAssigned VolunteerCommentsScheduledActions
+ + {{ call.voter.first_name }} {{ call.voter.last_name }} + + + {% if call.voter.phone %} + + {% else %} + - + {% endif %} + + {% if call.volunteer %} + + {{ call.volunteer }} + + {% else %} + Unassigned + {% endif %} + {{ call.comments|default:"-" }}{{ call.created_at|timesince }} ago + +
+ {% csrf_token %} + +
+
+

The call queue is currently empty.

+
+
+ + {% if calls.paginator.num_pages > 1 %} + + {% endif %} +
+
+ + + + + +{% endblock %} \ No newline at end of file diff --git a/core/templates/core/volunteer_detail.html b/core/templates/core/volunteer_detail.html index 67bda37..a57e425 100644 --- a/core/templates/core/volunteer_detail.html +++ b/core/templates/core/volunteer_detail.html @@ -23,9 +23,9 @@ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; } .ts-control.focus { - border-color: #86b7fe !important; + border-color: #059669 !important; outline: 0 !important; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25) !important; + box-shadow: 0 0 0 0.25rem rgba(5, 150, 105, 0.1) !important; } {% endblock %} @@ -71,7 +71,6 @@ {{ form.email }} -
@@ -84,6 +83,14 @@
{{ form.phone }}
+
+
+ {{ form.is_default_caller }} + +
If enabled, this volunteer will be the default assigned person for new call queue entries.
+
@@ -141,7 +148,7 @@
{{ assignment.event.date|date:"M d, Y" }}
- {{ assignment.role }} + {{ assignment.role_type|default:"Assigned" }}
{% csrf_token %} @@ -229,9 +236,9 @@ {{ assign_form.event }}
- - {{ assign_form.role }} -
e.g., Door knocker, Registration desk, Driver
+ + {{ assign_form.role_type }} +
e.g., Phone Banker, Door knocker, Registration desk