diff --git a/backend/src/mongodb/speaker.go b/backend/src/mongodb/speaker.go index f7c6e77b..667fa2f6 100644 --- a/backend/src/mongodb/speaker.go +++ b/backend/src/mongodb/speaker.go @@ -127,7 +127,9 @@ func (s *SpeakersType) CreateSpeaker(data CreateSpeakerData) (*models.Speaker, e ctx := context.Background() contact := bson.M{ - "phones": []models.ContactPhone{}, + "gender": data.Contact.Gender, + "language": data.Contact.Language, + "phones": []models.ContactPhone{}, "socials": bson.M{ "facebook": "", "skype": "", diff --git a/frontend/public/templates/speakers/33-pt.html b/frontend/public/templates/speakers/33-pt.html index 6a195f66..28a8f777 100644 --- a/frontend/public/templates/speakers/33-pt.html +++ b/frontend/public/templates/speakers/33-pt.html @@ -236,20 +236,16 @@ " >

- Caro/a/e {{.Speaker}}, + Car{{.SpeakerArticle}} {{.Speaker}},

- Sou o/a/e {{.Member}}, um - orgulhoso membro da SINFO. Em nome da equipa organizadora da - SINFO {{.Edition}}, convidamo-lo/a/e - a participar como orador(a) de uma - palestra no nosso evento. Ficaríamos muito gratos pela - oportunidade de recebê-lo/a/e se - aceitar este convite. + Sou {{.MemberArticle}} {{.Member}}, um{{.MemberSuffix}} + orgulhos{{.MemberArticle}} membro da SINFO. Em nome da + equipa organizadora da SINFO {{.Edition}}, + convidamo-l{{.SpeakerArticle}} a participar como + orador{{.SpeakerSuffix}} de uma palestra no nosso evento. + Ficaríamos muito gratos pela oportunidade de + recebê-l{{.SpeakerArticle}} se aceitar este convite.

@@ -409,9 +405,8 @@ {{if .Paragraph}} {{.Paragraph}} {{else}} A maioria dos nossos visitantes são estudantes de Informática ansiosos por começar as suas carreiras e seria com muito prazer que iam - ouvi-lo/a falar sobre o seu - percurso profissional e aprender com a sua experiência! - {{end}} + ouvi-l{{.SpeakerArticle}} falar sobre o seu percurso + profissional e aprender com a sua experiência! {{end}}


diff --git a/frontend/src/components/BulkEmailDialogTrigger.vue b/frontend/src/components/BulkEmailDialogTrigger.vue index 31adcccb..d02edcff 100644 --- a/frontend/src/components/BulkEmailDialogTrigger.vue +++ b/frontend/src/components/BulkEmailDialogTrigger.vue @@ -450,7 +450,7 @@ import { import { humanReadableParticipationStatus } from "@/dto/index"; import type { ParticipationStatus } from "@/dto/index"; import type { CompanyWithParticipation } from "@/dto/companies"; -import type { SpeakerWithParticipation } from "@/dto/speakers"; +import type { SpeakerWithContactAndParticipation } from "@/dto/speakers"; import { useBulkCompanyEmails, useBulkSpeakerEmails, @@ -462,7 +462,7 @@ interface Props { size?: "sm" | "default" | "lg" | "icon"; buttonClass?: string; companies?: CompanyWithParticipation[]; - speakers?: SpeakerWithParticipation[]; + speakers?: SpeakerWithContactAndParticipation[]; entityType: "companies" | "speakers"; } @@ -499,7 +499,7 @@ const speakerBulk = useBulkSpeakerEmails(); const processBulkEmails = async ( templateCategory: EmailTemplateCategory, statuses: ParticipationStatus[], - entities: CompanyWithParticipation[] | SpeakerWithParticipation[], + entities: CompanyWithParticipation[] | SpeakerWithContactAndParticipation[], ) => { if (props.entityType === "companies") { return companyBulk.processBulkEmails( @@ -511,7 +511,7 @@ const processBulkEmails = async ( return speakerBulk.processBulkEmails( templateCategory, statuses, - entities as SpeakerWithParticipation[], + entities as SpeakerWithContactAndParticipation[], ); }; diff --git a/frontend/src/components/Communications.vue b/frontend/src/components/Communications.vue index e238268f..fe5e75f7 100644 --- a/frontend/src/components/Communications.vue +++ b/frontend/src/components/Communications.vue @@ -153,17 +153,6 @@ > {{ getKindLabel(thread.kind) }} - -
-
- {{ getStatusLabel(thread.status) }} -
- {{ formatDate(thread.posted) }} @@ -350,7 +339,7 @@ import { ref, computed, watch, nextTick } from "vue"; import { useQuery } from "@pinia/colada"; import { getAllEvents } from "@/api/events"; import { getAllMembers } from "@/api/members"; -import { ThreadKind, ThreadStatus } from "@/dto/threads"; +import { ThreadKind } from "@/dto/threads"; import type { ParticipationCommunications, ThreadWithEntry, @@ -704,32 +693,6 @@ const getKindColor = (kind: ThreadKind): string => { } }; -const getStatusLabel = (status: ThreadStatus): string => { - switch (status) { - case ThreadStatus.ThreadStatusApproved: - return "Approved"; - case ThreadStatus.ThreadStatusReviewed: - return "Reviewed"; - case ThreadStatus.ThreadStatusPending: - return "Pending"; - default: - return "Unknown"; - } -}; - -const getStatusColor = (status: ThreadStatus): string => { - switch (status) { - case ThreadStatus.ThreadStatusApproved: - return "bg-green-500"; - case ThreadStatus.ThreadStatusReviewed: - return "bg-yellow-500"; - case ThreadStatus.ThreadStatusPending: - return "bg-red-500"; - default: - return "bg-gray-400"; - } -}; - const formatDate = (dateString: string): string => { const date = new Date(dateString); const now = new Date(); diff --git a/frontend/src/components/companies/ContactForm.vue b/frontend/src/components/companies/ContactForm.vue index 44311468..38057c61 100644 --- a/frontend/src/components/companies/ContactForm.vue +++ b/frontend/src/components/companies/ContactForm.vue @@ -16,7 +16,7 @@
- +
- +
+ + +
+

+ {{ validationMessage }} +

+
@@ -350,20 +362,29 @@ watch( { immediate: true }, ); -watch( - () => formData, - (newData) => emit("updated", newData), - { deep: true, immediate: true }, -); - const isValid = computed(() => { const hasName = props.withoutName || formData.name?.trim(); const hasEmail = formData.contact.mails.some((mail) => mail.mail.trim()); - return hasName && hasEmail; + const hasGender = !!formData.contact.gender; + const hasLanguage = !!formData.contact.language; + + return hasName && hasEmail && hasGender && hasLanguage; }); +watch( + () => formData, + (newData) => { + if (isValid.value) { + emit("updated", newData); + } + }, + { deep: true, immediate: true }, +); + const validationMessage = computed(() => { if (!props.withoutName && !formData.name?.trim()) return "Name is required"; + if (!formData.contact.gender) return "Gender is required"; + if (!formData.contact.language) return "Language is required"; if (!formData.contact.mails.some((mail) => mail.mail.trim())) return "At least one email is required"; return ""; diff --git a/frontend/src/components/speakers/CreateSpeakerForm.vue b/frontend/src/components/speakers/CreateSpeakerForm.vue index 8e483992..9807911d 100644 --- a/frontend/src/components/speakers/CreateSpeakerForm.vue +++ b/frontend/src/components/speakers/CreateSpeakerForm.vue @@ -160,7 +160,10 @@ Back
-
@@ -266,6 +269,17 @@ const isStep1Valid = computed(() => { ); }); +const isStep3Valid = computed(() => { + return ( + contactData.value.gender != undefined && + contactData.value.language != undefined && + contactData.value.mails && + contactData.value.mails.some( + (mail) => mail.mail && mail.mail.trim().length > 0, + ) + ); +}); + // Step navigation const nextStep = () => { if (currentStep.value === 1 && validateStep1()) { @@ -352,6 +366,8 @@ const createSpeakerAndFinish = async () => { (phone) => phone.phone && phone.phone.trim().length > 0, ), socials: contactData.value.socials || {}, + gender: contactData.value.gender, + language: contactData.value.language, }; const createData: CreateSpeakerData = { diff --git a/frontend/src/components/speakers/SpeakerCommunications.vue b/frontend/src/components/speakers/SpeakerCommunications.vue index 1d8fb89d..3dfe9b17 100644 --- a/frontend/src/components/speakers/SpeakerCommunications.vue +++ b/frontend/src/components/speakers/SpeakerCommunications.vue @@ -13,7 +13,7 @@