Skip to content

Commit

Permalink
Merge branch 'release/votepeloclima' into feature/candidate-search
Browse files Browse the repository at this point in the history
  • Loading branch information
igr-santos committed Aug 29, 2024
2 parents f308f65 + 70f5173 commit 18b296b
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 41 deletions.
58 changes: 58 additions & 0 deletions app/org_eleicoes/votepeloclima/candidature/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from django.contrib import admin
from django import forms
from entangled.forms import EntangledModelForm

from .models import Candidature, CandidatureFlow

Expand All @@ -11,9 +13,65 @@ def has_add_permission(self, request):
return False


class CandidatureFlowAdminForm(EntangledModelForm):
legal_name = forms.CharField(label='Nome Legal', required=True)
cpf = forms.CharField(label='CPF', required=True)
email = forms.EmailField(label='Email', required=True)
birth_date = forms.DateField(
label='Data de Nascimento',
required=False,
widget=forms.DateInput(attrs={'type': 'date'})
)
ballot_name = forms.CharField(label='Nome na Urna', required=True)
number_id = forms.CharField(label='Número de Identificação', required=True)
intended_position = forms.CharField(label='Cargo Pretendido', required=True)
state = forms.CharField(label='Estado', required=True)
city = forms.CharField(label='Cidade', required=True)
political_party = forms.CharField(label='Partido Político', required=True)
deputy_mayor = forms.CharField(label='Vice-prefeito', required=False)
deputy_mayor_political_party = forms.CharField(label='Partido do Vice-prefeito', required=False)

class Meta:
model = CandidatureFlow
entangled_fields = {'properties': [
'legal_name', 'cpf', 'email', 'birth_date',
'ballot_name', 'number_id', 'intended_position',
'state', 'city', 'political_party',
'deputy_mayor', 'deputy_mayor_political_party'
]}
untangled_fields = ['photo', 'video', 'status']


class CandidatureFlowAdmin(admin.ModelAdmin):
form = CandidatureFlowAdminForm
list_filter = ("status", )
list_display = ("legal_name", "email", "political_party", "status")

fieldsets = (
(None, {
'fields': ('photo', 'video', 'status')
}),
('Informações Pessoais', {
'fields': (
'legal_name',
'cpf',
'email',
'birth_date'
)
}),
('Dados de Candidatura', {
'fields': (
'ballot_name',
'number_id',
'intended_position',
'state',
'city',
'political_party',
'deputy_mayor',
'deputy_mayor_political_party'
)
}),
)

@admin.display
def legal_name(self, obj):
Expand Down
10 changes: 5 additions & 5 deletions app/org_eleicoes/votepeloclima/candidature/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,15 +311,15 @@ def clean(self):

class ProposeForm(EntangledModelFormMixin, DisabledMixin, forms.ModelForm):
transporte_e_mobilidade = CheckboxTextField(
checkbox_label="Transporte e Mobilidade",
checkbox_label="Transporte e mobilidade",
help_text="Transporte coletivo gratuito e de qualidade, modais com menos emissões e mobilidade ativa.",
text_label=propose_text_label,
text_help_text=propose_text_help_text,
required=False,
max_length=600
)
gestao_de_residuos = CheckboxTextField(
checkbox_label="Gestão de Resíduos",
checkbox_label="Gestão de resíduos",
help_text="Compostagem de resíduos orgânicos, economia circular, mais iniciativas de catadores e catadoras de materiais recicláveis, uso de materiais biodegradáveis.",
text_label=propose_text_label,
text_help_text=propose_text_help_text,
Expand All @@ -337,7 +337,7 @@ class ProposeForm(EntangledModelFormMixin, DisabledMixin, forms.ModelForm):

)
educacao_climatica = CheckboxTextField(
checkbox_label="Educação Climática",
checkbox_label="Educação climática",
help_text="Ensino sobre meio ambiente e mudanças climáticas nas escolas, formação profissional para empregos verdes, formação de agentes populares para gestão do risco climático.",
text_label=propose_text_label,
text_help_text=propose_text_help_text,
Expand All @@ -355,7 +355,7 @@ class ProposeForm(EntangledModelFormMixin, DisabledMixin, forms.ModelForm):

)
moradia_digna = CheckboxTextField(
checkbox_label="Moradia Digna",
checkbox_label="Moradia digna",
help_text="Políticas habitacionais justas e participativas, moradia resiliente aos impactos de eventos climáticos extremos, eficiência hídrica e energética.",
text_label=propose_text_label,
text_help_text=propose_text_help_text,
Expand All @@ -382,7 +382,7 @@ class ProposeForm(EntangledModelFormMixin, DisabledMixin, forms.ModelForm):

)
direito_a_cidade = CheckboxTextField(
checkbox_label="Direito à Cidade",
checkbox_label="Direito à cidade",
help_text="Mais áreas verdes e parques públicos, menos ilhas de calor, segurança pública e bem-estar urbano, cidades mais sustentáveis e inclusivas.",
text_label=propose_text_label,
text_help_text=propose_text_help_text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def get_proposes_choices(self):
form = ProposeForm()
choices = []
for field_name in form.fields:
if field_name is not "properties":
if field_name != "properties":
choices.append((field_name, form.fields[field_name].checkbox_label))

return choices
Expand Down
64 changes: 32 additions & 32 deletions app/org_eleicoes/votepeloclima/candidature/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,32 @@
# Acompanhar validação da candidatura
# Armazenar e acompanhar etapas do preenchimento das informações


class Candidature(models.Model):
legal_name = models.CharField(verbose_name="Nome", max_length=150)
ballot_name = models.CharField(verbose_name="Nome na urna", max_length=100)
birth_date = models.DateField(verbose_name="Data de nascimento")
email = models.EmailField()
cpf = models.CharField(max_length=30)
number_id = models.PositiveIntegerField()
intended_position = models.CharField(verbose_name="Tipo de candidatura", max_length=50, choices=IntendedPosition.choices)
deputy_mayor = models.CharField(max_length=140, blank=True, null=True)
deputy_mayor_political_party = models.CharField(max_length=60, blank=True, null=True)
state = models.CharField(verbose_name="Estado", max_length=10)
city = models.CharField(verbose_name="Município", max_length=60)
is_collective_mandate = models.BooleanField(verbose_name="Tipo de mandato", default=False, blank=True)
political_party = models.CharField(verbose_name="Partido político", max_length=60, choices=PoliticalParty.choices)
video = models.FileField(upload_to="candidatures/videos/", null=True, blank=True)
photo = models.FileField(upload_to="candidatures/photos/", null=True, blank=True)
gender = models.CharField(max_length=30)
color = models.CharField(max_length=30)
sexuality = models.CharField(max_length=30, null=True, blank=True, choices=Sexuality.choices)
social_media = models.JSONField(blank=True, null=True, default=list)
education = models.CharField(max_length=50, null=True, blank=True, choices=Education.choices)
employment = models.CharField(max_length=50, null=True, blank=True)
short_description = models.TextField()
milestones = models.JSONField(blank=True, null=True, default=list)
proposes = models.JSONField(blank=True)
appointments = models.JSONField(blank=True)
legal_name = models.CharField(max_length=150, verbose_name="Nome")
ballot_name = models.CharField(max_length=100, verbose_name="Nome na Urna")
birth_date = models.DateField(verbose_name="Data de Nascimento")
email = models.EmailField(verbose_name="E-mail")
cpf = models.CharField(max_length=30, verbose_name="CPF")
number_id = models.PositiveIntegerField(verbose_name="Número na Urna")
intended_position = models.CharField(max_length=50, choices=IntendedPosition.choices, verbose_name="Cargo Pretendido")
deputy_mayor = models.CharField(max_length=140, blank=True, null=True, verbose_name="Vice-prefeito")
deputy_mayor_political_party = models.CharField(max_length=60, blank=True, null=True, verbose_name="Partido do Vice-prefeito")
state = models.CharField(max_length=10, verbose_name="Estado")
city = models.CharField(max_length=60, verbose_name="Cidade")
is_collective_mandate = models.BooleanField(default=False, blank=True, verbose_name="Mandato Coletivo")
political_party = models.CharField(max_length=60, choices=PoliticalParty.choices, verbose_name="Partido Político")
video = models.FileField(upload_to="candidatures/videos/", null=True, blank=True, verbose_name="Vídeo")
photo = models.FileField(upload_to="candidatures/photos/", null=True, blank=True, verbose_name="Foto")
gender = models.CharField(max_length=30, verbose_name="Gênero")
color = models.CharField(max_length=30, verbose_name="Raça")
sexuality = models.CharField(max_length=30, null=True, blank=True, choices=Sexuality.choices, verbose_name="Sexualidade")
social_media = models.JSONField(blank=True, null=True, default=list, verbose_name="Redes Sociais")
education = models.CharField(max_length=50, null=True, blank=True, choices=Education.choices, verbose_name="Educação")
employment = models.CharField(max_length=50, null=True, blank=True, verbose_name="Ocupação")
short_description = models.TextField(verbose_name="Descrição Curta")
milestones = models.JSONField(blank=True, null=True, default=list, verbose_name="Marcos")
proposes = models.JSONField(blank=True, verbose_name="Propostas")
appointments = models.JSONField(blank=True, verbose_name="Compromissos")

# friendly url by ballot_name
slug = models.SlugField(max_length=100, unique=True, blank=True, null=True)
Expand Down Expand Up @@ -91,37 +90,38 @@ def save(self, *args, **kwargs):

class CandidatureFlow(models.Model):
# Propriedades só podem ser editadas quando status for `draft`
photo = models.ImageField(upload_to="candidatures/photos/", null=True)
video = models.FileField(upload_to="candidatures/videos/", null=True, blank=True)
photo = models.ImageField(upload_to="candidatures/photos/", null=True, verbose_name="Foto")
video = models.FileField(upload_to="candidatures/videos/", null=True, blank=True, verbose_name="Vídeo")

properties = models.JSONField(blank=True, encoder=DjangoJSONEncoder, default=dict)
properties = models.JSONField(blank=True, encoder=DjangoJSONEncoder, default=dict, verbose_name="Propriedades")
status = models.CharField(
max_length=50,
choices=CandidatureFlowStatus.choices,
default=CandidatureFlowStatus.draft,
verbose_name="Status",
)

# Registro das etapas de validação
# Quem validou? Manual, Bot
# Quando foi validado? Data da ação
# Validado ou não
# Comentário sobre
validations = models.JSONField(blank=True, null=True)
validations = models.JSONField(blank=True, null=True, verbose_name="Validações")

# Etapa 2
# - Preenchimento da Candidatura
# - Envio da Candidatura para avaliação
# - Validadores automatizados
# - Validatores manuais
candidature = models.OneToOneField(
Candidature, null=True, on_delete=models.SET_NULL
Candidature, null=True, blank=True, on_delete=models.SET_NULL, verbose_name="Candidatura"
)

# Etapa 1
# - Criar usuário desabilitado `is_active=False`
# - Enviar e-mail para validar o usuário e criar uma senha de acesso
# - Habilitar usuário `is_active=True`
user = models.OneToOneField(User, null=True, on_delete=models.SET_NULL)
user = models.OneToOneField(User, null=True, on_delete=models.SET_NULL, verbose_name="Usuário")

class Meta:
verbose_name = "Formulário"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ <h2 class="text-center text-uppercase fw-bold">O que esperar de {{ candidature.b
</div>


<p class="text-center">*As organizações da plataforma não se comprometem com a efetividade e execução dos compromissos firmados. O controle social e a participação ativa da cidadania são fundamentais para que parlamentares e gestores públicos cumpram suas promessas.</p>
<p class="text-center">*As organizações da plataforma não se responsabilizam pela efetivação dos compromissos declarados pelas candidaturas. O controle social e a participação ativa da cidadania são fundamentais para que parlamentares e gestores públicos cumpram suas promessas.</p>
</div>
</section>
<hr class="w-100" />
Expand All @@ -151,7 +151,6 @@ <h2 class="fw-bold text-uppercase mb-3">Compartilhe nas redes sociais
</div>
</div>
<div class="g-col-12 g-col-md-4">
<p class="fw-bold text-uppercase">Compartilhe em:</p>
<div class="d-flex flex-column justify-content-center gap-2">
<a class="btn btn-primary text-uppercase d-inline-flex justify-content-center align-items-center gap-1" href="https://wa.me/?text=Oi! As eleições estão chegando e o futuro da nossa cidade depende do nosso voto. Compartilho com você uma das candidaturas comprometidas na luta pelo meio ambiente e contra as ameaças climáticas. Conheça as propostas na plataforma *Vote pelo Clima!* {{ request.build_absolute_uri|urlencode }}">
<span class="ds-icon-whatsapp"></span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h2 class="text-uppercase fw-bold">Conheça candidaturas da sua cidade</h2>
<div class="g-col-12">
<div class="search-header">
{% crispy form.header %}
<button class="btn btn-primary" type="submit"><i class="ds-icon-search"></i></button>
<button class="btn btn-primary" type="submit"><i class="ds-icon-search"></i><span class="d-inline-block d-md-none mx-auto">Buscar</span></button>
</div>
</div>
<!-- Sidebar -->
Expand Down

0 comments on commit 18b296b

Please sign in to comment.