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 @@
-
Gender
+
Gender *
- Language
+ Language *
+
+
+
+
+ {{ 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
-
+
Create Speaker
@@ -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 @@