(null);
- const resetInput = () => {
+ const resetInput = (triggerOnChange = true) => {
setError("");
if (filePreview) {
URL.revokeObjectURL(filePreview);
- baseOnChange(null);
+ if (triggerOnChange) {
+ baseOnChange(null);
+ }
}
setFilePreview(null);
};
const onChange = (file: File) => {
- setSelectedFile(file);
- console.log("file", file);
-
if (!file) {
resetInput();
return;
@@ -74,13 +81,19 @@ export const FileInput = ({
return;
}
- resetInput();
- const fakeImg = document.createElement("img");
- fakeImg.onload = () => onImageLoaded(fakeImg);
- fakeImg.src = URL.createObjectURL(file);
+ resetInput(false);
+ setSelectedFile(file);
+
+ if (file.type.startsWith("image/")) {
+ const fakeImg = document.createElement("img");
+ fakeImg.onload = () => onImageLoaded(fakeImg, file);
+ fakeImg.src = URL.createObjectURL(file);
+ } else {
+ startUploadFlow(file);
+ }
};
- const onImageLoaded = (image: HTMLImageElement) => {
+ const onImageLoaded = (image: HTMLImageElement, fileInfo: File) => {
// convert the image to jpeg
// in the future this could do more (resize etc)
const context = canvas.current.getContext("2d");
@@ -89,7 +102,7 @@ export const FileInput = ({
context.drawImage(image, 0, 0);
canvas.current.toBlob(
(blob) => {
- const file = new File([blob], "converted.jpg", {
+ const file = new File([blob], `${fileInfo.name.split(".")[0]}.jpg`, {
type: "application/octet-stream",
});
setFilePreview(URL.createObjectURL(file));
@@ -109,26 +122,35 @@ export const FileInput = ({
participantAvatar: {
conferenceCode,
filename: file.name,
+ ...fileAttributes,
+ },
+ };
+ } else if (type === "proposal_material") {
+ input = {
+ proposalMaterial: {
+ conferenceCode,
+ filename: file.name,
+ ...fileAttributes,
},
};
}
- const { data, errors } = await uploadFile({
- variables: {
- input,
- },
- });
+ try {
+ const { data, errors } = await uploadFile({
+ variables: {
+ input,
+ },
+ });
- const response = data.uploadFile;
+ const response = data.uploadFile;
- if (errors || response.__typename !== "FileUploadRequest") {
- setError(getTranslatedMessage("fileInput.uploadFailed", language));
- return;
- }
+ if (errors || response.__typename !== "FileUploadRequest") {
+ setError(getTranslatedMessage("fileInput.uploadFailed", language));
+ return;
+ }
- const uploadUrl = response.uploadUrl;
- const uploadFields = JSON.parse(response.fields);
- try {
+ const uploadUrl = response.uploadUrl;
+ const uploadFields = JSON.parse(response.fields);
const formData = new FormData();
Object.keys(uploadFields).forEach((key) => {
formData.append(key, uploadFields[key]);
@@ -154,9 +176,15 @@ export const FileInput = ({
},
});
- baseOnChange(fileId);
+ baseOnChange(fileId, {
+ name: file.name,
+ });
} catch (e) {
- setError(getTranslatedMessage("fileInput.uploadFailed", language));
+ const baseMessage = getTranslatedMessage(
+ "fileInput.uploadFailed",
+ language,
+ );
+ setError(`${baseMessage}: ${e.message}`);
} finally {
setIsUploading(false);
}
@@ -177,21 +205,27 @@ export const FileInput = ({
errors={allErrors}
/>
-
-
- {isUploading && (
-
-
-
- )}
-
- {previewAvailable && (
+
+ {isUploading && }
+ {!isUploading && !showPreview && currentFileName && (
+
+ )}
+
+
+ {previewAvailable && showPreview && (
)}
+
+
);
};
diff --git a/frontend/src/components/my-proposals-profile-page-handler/my-proposals-table.tsx b/frontend/src/components/my-proposals-profile-page-handler/my-proposals-table.tsx
index 4c27234305..20e5eb58b3 100644
--- a/frontend/src/components/my-proposals-profile-page-handler/my-proposals-table.tsx
+++ b/frontend/src/components/my-proposals-profile-page-handler/my-proposals-table.tsx
@@ -53,15 +53,7 @@ export const MyProposalsTable = ({ submissions }: Props) => {
,
- row.status === "accepted" ? (
- inSchedule ? (
-
- ) : (
-
- )
- ) : (
-
- ),
+ ,
{inSchedule &&
row.scheduleItems.map((scheduleItem) => {
diff --git a/frontend/src/components/submission/submission.graphql b/frontend/src/components/submission/submission.graphql
index 2219becc2e..2f54bee41c 100644
--- a/frontend/src/components/submission/submission.graphql
+++ b/frontend/src/components/submission/submission.graphql
@@ -28,6 +28,14 @@ query Submission($id: ID!, $language: String!) {
id
name
}
+ materials {
+ id
+ name
+ url
+ fileId
+ fileUrl
+ fileMimeType
+ }
speaker {
id
fullName
diff --git a/frontend/src/locale/index.ts b/frontend/src/locale/index.ts
index 229d2b4552..c245fd71a9 100644
--- a/frontend/src/locale/index.ts
+++ b/frontend/src/locale/index.ts
@@ -12,6 +12,8 @@ export const messages = {
"tickets.description.page": "hotels page",
"global.sessions": "Sessions",
+ "cfp.materials.remove": "X",
+ "fileInput.currentFile": "Current file: {name}",
"input.placeholder": "Type here...",
"global.accordion.close": "Close",
@@ -663,7 +665,8 @@ Click the box to change. If left empty, we will assume you are available.`,
"orderInformation.invalidFiscalCode": "Fiscal code not valid",
"orderInformation.pec": "PEC",
"orderInformation.sdi": "SDI",
- "orderInformation.invalidSDI": "SDI must be 7 characters long (6 for Italian PA)",
+ "orderInformation.invalidSDI":
+ "SDI must be 7 characters long (6 for Italian PA)",
"orderQuestions.heading": "Order questions",
"orderQuestions.attendeeGivenName": "Attendee Given name",
@@ -1002,6 +1005,13 @@ If this new timing doesn't work for you, please don't hesitate to let us know be
"streaming.qa": "Ask Questions",
+ "cfp.materials.addFile": "File",
+ "cfp.materials.addURL": "URL",
+ "cfp.materials.add": "Add",
+ "cfp.materials.title": "Materials",
+ "cfp.materials.description":
+ "Use this section to upload the slides or other materials you want to share with other attendees. Up to 3 files/urls are allowed.",
+
"talk.bookToAttend":
"This event has limited capacity, you need to book a seat to attend.",
"talk.bookCta": "Book now",
@@ -1447,7 +1457,8 @@ The sooner you buy your ticket, the more you save!`,
"orderInformation.invalidFiscalCode": "Codice fiscale non valido",
"orderInformation.pec": "PEC",
"orderInformation.sdi": "SDI",
- "orderInformation.invalidSDI": "Il codice SDI deve essere di 7 caratteri (6 per una PA)",
+ "orderInformation.invalidSDI":
+ "Il codice SDI deve essere di 7 caratteri (6 per una PA)",
"orderQuestions.heading": "Domande aggiuntive",
"orderQuestions.attendeeName": "Nome partecipante",
@@ -2291,6 +2302,15 @@ Clicca sulla casella per cambiare. Se lasciato vuoto, presumeremo che tu sia dis
"voting.filterBy": "Filtra per",
"voting.all": "Tutti",
+
+ "cfp.materials.title": "Materiali",
+ "cfp.materials.description":
+ "Usa questa sezione per caricare i materiali che vuoi condividere con altri partecipanti. Sono consentiti fino a 3 file/URL.",
+ "cfp.materials.addFile": "File",
+ "cfp.materials.addURL": "URL",
+ "cfp.materials.add": "Aggiungi",
+ "cfp.materials.remove": "X",
+ "fileInput.currentFile": "File attuale: {name}",
},
};
diff --git a/frontend/src/pages/keynotes/[slug]/index.tsx b/frontend/src/pages/keynotes/[slug]/index.tsx
index 042ab906cf..5efff0c9f4 100644
--- a/frontend/src/pages/keynotes/[slug]/index.tsx
+++ b/frontend/src/pages/keynotes/[slug]/index.tsx
@@ -20,9 +20,7 @@ const KeynotePage = () => {
const {
data: {
conference: {
- talk: {
- slidoUrl,
- },
+ talk,
keynote: {
title,
description,
@@ -42,6 +40,8 @@ const KeynotePage = () => {
},
});
+ const { slidoUrl } = talk || {};
+
const speakersName = speakers.map((speaker) => speaker.fullName).join(" & ");
return (
diff --git a/frontend/src/pages/submission/[id]/edit/get-submission.graphql b/frontend/src/pages/submission/[id]/edit/get-submission.graphql
index ea5b8ef374..e4cb4d0f31 100644
--- a/frontend/src/pages/submission/[id]/edit/get-submission.graphql
+++ b/frontend/src/pages/submission/[id]/edit/get-submission.graphql
@@ -1,6 +1,7 @@
query GetSubmission($id: ID!, $language: String!) {
submission(id: $id) {
id
+ status
title(language: $language)
abstract(language: $language)
elevatorPitch(language: $language)
@@ -46,5 +47,13 @@ query GetSubmission($id: ID!, $language: String!) {
id
name
}
+ materials {
+ id
+ name
+ url
+ fileId
+ fileUrl
+ fileMimeType
+ }
}
}
diff --git a/frontend/src/pages/submission/[id]/edit/index.tsx b/frontend/src/pages/submission/[id]/edit/index.tsx
index 17340eb91a..8f26ee0fe7 100644
--- a/frontend/src/pages/submission/[id]/edit/index.tsx
+++ b/frontend/src/pages/submission/[id]/edit/index.tsx
@@ -68,6 +68,14 @@ export const EditSubmissionPage = () => {
speakerFacebookUrl: input.participantFacebookUrl,
speakerMastodonHandle: input.participantMastodonHandle,
speakerAvailabilities: input.speakerAvailabilities,
+ materials: input.materials
+ .filter((material) => material.fileId || material.url)
+ .map((material) => ({
+ name: material.name,
+ id: material.id,
+ url: material.url,
+ fileId: material.fileId,
+ })),
},
language,
},
diff --git a/frontend/src/pages/submission/[id]/edit/update-submission.graphql b/frontend/src/pages/submission/[id]/edit/update-submission.graphql
index cbd7c27f4f..80edf53155 100644
--- a/frontend/src/pages/submission/[id]/edit/update-submission.graphql
+++ b/frontend/src/pages/submission/[id]/edit/update-submission.graphql
@@ -51,6 +51,14 @@ mutation UpdateSubmission($input: UpdateSubmissionInput!, $language: String!) {
id
name
}
+ materials {
+ id
+ name
+ url
+ fileId
+ fileUrl
+ fileMimeType
+ }
}
... on SendSubmissionErrors {
@@ -76,6 +84,10 @@ mutation UpdateSubmission($input: UpdateSubmissionInput!, $language: String!) {
validationSpeakerLinkedinUrl: speakerLinkedinUrl
validationSpeakerFacebookUrl: speakerFacebookUrl
validationSpeakerMastodonHandle: speakerMastodonHandle
+ validationMaterials: materials {
+ fileId
+ url
+ }
nonFieldErrors
}
}
diff --git a/frontend/src/pages/submission/[id]/index.tsx b/frontend/src/pages/submission/[id]/index.tsx
index 8d17fb947b..2ae64be8e6 100644
--- a/frontend/src/pages/submission/[id]/index.tsx
+++ b/frontend/src/pages/submission/[id]/index.tsx
@@ -79,6 +79,7 @@ export const SubmissionPage = () => {
speakers={submission?.speaker ? [submission.speaker] : null}
bookable={false}
spacesLeft={0}
+ materials={submission?.materials}
sidebarExtras={
{submission.canEdit ? (