diff --git a/public/locales/bg/validation.json b/public/locales/bg/validation.json
index d341eb735..26d075d9a 100644
--- a/public/locales/bg/validation.json
+++ b/public/locales/bg/validation.json
@@ -22,5 +22,6 @@
"payment-reference": "Невалиден формат на кода за плащане",
"eik-invalid": "Невалидно ЕИК",
"help-us-improve": "Съгласявам се да се свържете с мен за подобрение на платформата.",
- "positive-amount": "Сумата трябва да е положително число."
+ "positive-amount": "Сумата трябва да е положително число.",
+ "invalid-file": "Невалиден файл."
}
diff --git a/public/locales/en/validation.json b/public/locales/en/validation.json
index 5225bf637..e3584afce 100644
--- a/public/locales/en/validation.json
+++ b/public/locales/en/validation.json
@@ -22,5 +22,6 @@
"payment-reference": "Invalid payment code format",
"eik-invalid": "Invalid EIK",
"help-us-improve": "I agree to be contacted to help improve the platform.",
- "positive-amount": "The amount must be a positive number."
+ "positive-amount": "The amount must be a positive number.",
+ "invalid-file": "Invalid file."
}
diff --git a/src/components/admin/campaigns/grid/CreateForm.tsx b/src/components/admin/campaigns/grid/CreateForm.tsx
index 5432a7ae0..f0c87da97 100644
--- a/src/components/admin/campaigns/grid/CreateForm.tsx
+++ b/src/components/admin/campaigns/grid/CreateForm.tsx
@@ -25,7 +25,13 @@ const FormRichTextField = dynamic(() => import('components/common/form/FormRichT
ssr: false,
})
-import { ApiErrors, handleUniqueViolation, isAxiosError, matchValidator } from 'service/apiErrors'
+import {
+ ApiErrors,
+ handleFileUploadError,
+ handleUniqueViolation,
+ isAxiosError,
+ matchValidator,
+} from 'service/apiErrors'
import { useCreateCampaign, useUploadCampaignFiles } from 'service/campaign'
import {
CampaignFileRole,
@@ -137,6 +143,7 @@ export default function CampaignForm({ initialValues = defaults }: CampaignFormP
UploadCampaignFiles
>({
mutationFn: useUploadCampaignFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const onSubmit = async (
diff --git a/src/components/admin/campaigns/grid/EditForm.tsx b/src/components/admin/campaigns/grid/EditForm.tsx
index 44a4772f1..1a4735cd0 100644
--- a/src/components/admin/campaigns/grid/EditForm.tsx
+++ b/src/components/admin/campaigns/grid/EditForm.tsx
@@ -23,7 +23,13 @@ const FormRichTextField = dynamic(() => import('components/common/form/FormRichT
ssr: false,
})
-import { ApiErrors, handleUniqueViolation, isAxiosError, matchValidator } from 'service/apiErrors'
+import {
+ ApiErrors,
+ handleFileUploadError,
+ handleUniqueViolation,
+ isAxiosError,
+ matchValidator,
+} from 'service/apiErrors'
import {
CampaignResponse,
CampaignInput,
@@ -167,7 +173,7 @@ export default function EditForm({ campaign }: { campaign: AdminSingleCampaignRe
UploadCampaignFiles
>({
mutationFn: useUploadCampaignFiles(),
- onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
+ onError: (error) => handleFileUploadError(error, t),
onSuccess: () => {
//invalidate query for getting new values
queryClient.invalidateQueries([endpoints.campaign.viewCampaignById(campaign.id).url])
diff --git a/src/components/admin/donations/AddBankTransactionsFileForm.tsx b/src/components/admin/donations/AddBankTransactionsFileForm.tsx
index cac392ceb..2a6939f57 100644
--- a/src/components/admin/donations/AddBankTransactionsFileForm.tsx
+++ b/src/components/admin/donations/AddBankTransactionsFileForm.tsx
@@ -22,7 +22,7 @@ import FileUpload from 'components/common/file-upload/FileUpload'
import GenericForm from 'components/common/form/GenericForm'
import SubmitButton from 'components/common/form/SubmitButton'
import FormTextField from 'components/common/form/FormTextField'
-import { ApiErrors, isAxiosError, matchValidator } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError, isAxiosError, matchValidator } from 'service/apiErrors'
import {
BankTransactionsFileType,
FileType,
@@ -72,7 +72,7 @@ export default function BankTransactionsFileForm({
UploadBankTransactionsFiles
>({
mutationFn: useUploadBankTransactionsFiles(),
- onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
+ onError: (error) => handleFileUploadError(error, t),
onSuccess: () => AlertStore.show(t('common:alerts.message-sent'), 'success'),
})
diff --git a/src/components/admin/irregularity/admin/grid/CreateForm.tsx b/src/components/admin/irregularity/admin/grid/CreateForm.tsx
index 0dc7c6e33..b8055301d 100644
--- a/src/components/admin/irregularity/admin/grid/CreateForm.tsx
+++ b/src/components/admin/irregularity/admin/grid/CreateForm.tsx
@@ -12,7 +12,7 @@ import { CampaignResponse } from 'gql/campaigns'
import { Button, Grid } from '@mui/material'
-import { ApiErrors } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError } from 'service/apiErrors'
import { createIrregularity, uploadIrregularityFiles } from 'service/irregularity'
import { AlertStore } from 'stores/AlertStore'
import { routes } from 'common/routes'
@@ -90,6 +90,7 @@ export default function CreateForm({ campaigns, person }: Props) {
IrregularityInput
>({
mutationFn: createIrregularity,
+ onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
})
const fileUploadMutation = useMutation<
@@ -98,6 +99,7 @@ export default function CreateForm({ campaigns, person }: Props) {
UploadIrregularityFiles
>({
mutationFn: uploadIrregularityFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const onSubmit = async (values: IrregularityInput) => {
@@ -122,7 +124,7 @@ export default function CreateForm({ campaigns, person }: Props) {
AlertStore.show(t('common:alerts.message-sent'), 'success')
router.push(routes.admin.irregularity.index)
} catch (error) {
- AlertStore.show(t('common:alerts.error'), 'error')
+ console.error(error)
}
}
diff --git a/src/components/admin/irregularity/admin/grid/EditForm.tsx b/src/components/admin/irregularity/admin/grid/EditForm.tsx
index ec6c0ad69..8903d681a 100644
--- a/src/components/admin/irregularity/admin/grid/EditForm.tsx
+++ b/src/components/admin/irregularity/admin/grid/EditForm.tsx
@@ -10,7 +10,7 @@ import { AxiosError, AxiosResponse } from 'axios'
import { useMutation, useQueryClient } from '@tanstack/react-query'
-import { ApiErrors } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError } from 'service/apiErrors'
import { endpoints } from 'service/apiEndpoints'
import { editIrregularity, uploadIrregularityFiles } from 'service/irregularity'
@@ -98,6 +98,7 @@ export default function EditForm({ campaigns, irregularity, irregularityFiles }:
IrregularityEditInput
>({
mutationFn: editIrregularity(irregularity.id),
+ onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
})
const fileUploadMutation = useMutation<
@@ -106,6 +107,7 @@ export default function EditForm({ campaigns, irregularity, irregularityFiles }:
UploadIrregularityFiles
>({
mutationFn: uploadIrregularityFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const onSubmit = async (values: IrregularityEditInput) => {
@@ -132,7 +134,7 @@ export default function EditForm({ campaigns, irregularity, irregularityFiles }:
queryClient.invalidateQueries([endpoints.irregularity.viewIrregularity(irregularity.id).url])
router.push(routes.admin.irregularity.index)
} catch (error) {
- AlertStore.show(t('common:alerts.error'), 'error')
+ console.error(error)
}
}
diff --git a/src/components/client/campaign-application/steps/CampaignApplicationDetails.tsx b/src/components/client/campaign-application/steps/CampaignApplicationDetails.tsx
index b5454057c..10cd3dba6 100644
--- a/src/components/client/campaign-application/steps/CampaignApplicationDetails.tsx
+++ b/src/components/client/campaign-application/steps/CampaignApplicationDetails.tsx
@@ -66,7 +66,6 @@ export default function CampaignApplicationDetails({ files, setFiles }: Props) {
setFiles((prevFiles) => [...prevFiles, ...newFiles])
setFieldValue('applicationDetails.documents', newFiles)
}}
- accept="text/plain,application/json,application/pdf,image/png,image/jpeg,application/xml,text/xml,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
/>
{touched.applicationDetails?.documents && errors.applicationDetails?.documents && (
{t('steps.details.documents-hint')}
diff --git a/src/components/client/campaign-expenses/Form.tsx b/src/components/client/campaign-expenses/Form.tsx
index 289f7f750..3138dcf8e 100644
--- a/src/components/client/campaign-expenses/Form.tsx
+++ b/src/components/client/campaign-expenses/Form.tsx
@@ -21,7 +21,7 @@ import FormTextField from 'components/common/form/FormTextField'
import { Checkbox } from '@mui/material'
import { useCreateExpense, useEditExpense } from 'service/expense'
-import { ApiErrors, isAxiosError, matchValidator } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError, isAxiosError, matchValidator } from 'service/apiErrors'
import { ExpenseInput, ExpenseResponse, ExpenseStatus, ExpenseType } from 'gql/expenses'
import FileUpload from 'components/common/file-upload/FileUpload'
@@ -66,7 +66,7 @@ export default function Form() {
UploadExpenseFile
>({
mutationFn: useUploadExpenseFiles(),
- onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
+ onError: (error) => handleFileUploadError(error, t),
})
let data: ExpenseResponse | undefined
diff --git a/src/components/client/campaign-news/secured/CreateForm.tsx b/src/components/client/campaign-news/secured/CreateForm.tsx
index 58ca10d8e..595436483 100644
--- a/src/components/client/campaign-news/secured/CreateForm.tsx
+++ b/src/components/client/campaign-news/secured/CreateForm.tsx
@@ -22,7 +22,13 @@ const FormRichTextField = dynamic(() => import('components/common/form/FormRichT
ssr: false,
})
-import { ApiErrors, handleUniqueViolation, isAxiosError, matchValidator } from 'service/apiErrors'
+import {
+ ApiErrors,
+ handleFileUploadError,
+ handleUniqueViolation,
+ isAxiosError,
+ matchValidator,
+} from 'service/apiErrors'
import { useUploadCampaignNewsFiles } from 'service/campaign-news'
import {
CampaignFileRole,
@@ -111,6 +117,7 @@ export default function CreateForm({ campaignId = '', isAdmin = true }: Campaign
UploadCampaignNewsFiles
>({
mutationFn: useUploadCampaignNewsFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const onSubmit = async (
diff --git a/src/components/client/campaign-news/secured/EditForm.tsx b/src/components/client/campaign-news/secured/EditForm.tsx
index bed31df12..f23bdb421 100644
--- a/src/components/client/campaign-news/secured/EditForm.tsx
+++ b/src/components/client/campaign-news/secured/EditForm.tsx
@@ -27,7 +27,13 @@ const FormRichTextField = dynamic(() => import('components/common/form/FormRichT
ssr: false,
})
-import { ApiErrors, handleUniqueViolation, isAxiosError, matchValidator } from 'service/apiErrors'
+import {
+ ApiErrors,
+ handleFileUploadError,
+ handleUniqueViolation,
+ isAxiosError,
+ matchValidator,
+} from 'service/apiErrors'
import { CampaignUploadImage } from 'gql/campaigns'
import { ArticleStatus } from 'components/admin/campaign-news/helpers/article-status.enum'
import ArticleStatusSelect from 'components/admin/campaign-news/ArticleStatusSelect'
@@ -123,7 +129,7 @@ export default function EditForm({ article, campaignId = '', isAdmin = true }: P
UploadCampaignNewsFiles
>({
mutationFn: useUploadCampaignNewsFiles(),
- onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
+ onError: (error) => handleFileUploadError(error, t),
onSuccess: () => {
//invalidate query for getting new values
queryClient.invalidateQueries([endpoints.campaignNews.viewNewsArticleById(article.id).url])
diff --git a/src/components/client/campaigns/CampaignForm.tsx b/src/components/client/campaigns/CampaignForm.tsx
index 6172f09a6..b962b5331 100644
--- a/src/components/client/campaigns/CampaignForm.tsx
+++ b/src/components/client/campaigns/CampaignForm.tsx
@@ -25,7 +25,7 @@ import {
UploadCampaignFiles,
} from 'components/common/campaign-file/roles'
import AcceptTermsField from 'components/common/form/AcceptTermsField'
-import { ApiErrors, isAxiosError, matchValidator } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError, isAxiosError, matchValidator } from 'service/apiErrors'
import { useCreateCampaign, useUploadCampaignFiles } from 'service/campaign'
import {
CampaignResponse,
@@ -114,6 +114,7 @@ export default function CampaignForm({ initialValues = defaults }: CampaignFormP
UploadCampaignFiles
>({
mutationFn: useUploadCampaignFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const onSubmit = async (
diff --git a/src/components/client/irregularity/helpers/IrregularityForm.tsx b/src/components/client/irregularity/helpers/IrregularityForm.tsx
index edb651695..87a37abea 100644
--- a/src/components/client/irregularity/helpers/IrregularityForm.tsx
+++ b/src/components/client/irregularity/helpers/IrregularityForm.tsx
@@ -11,7 +11,7 @@ import { FormikHelpers, FormikProps } from 'formik'
import { StepLabel, Grid } from '@mui/material'
-import { ApiErrors, isAxiosError, matchValidator } from 'service/apiErrors'
+import { ApiErrors, handleFileUploadError, isAxiosError, matchValidator } from 'service/apiErrors'
import { createIrregularity, uploadIrregularityFiles } from 'service/irregularity'
import {
@@ -116,6 +116,7 @@ export default function IrregularityForm({ campaign, person }: Props) {
UploadIrregularityFiles
>({
mutationFn: uploadIrregularityFiles(),
+ onError: (error) => handleFileUploadError(error, t),
})
const handleBack = () => {
diff --git a/src/components/common/file-upload/FileUpload.tsx b/src/components/common/file-upload/FileUpload.tsx
index 9078029c2..76e2e033c 100644
--- a/src/components/common/file-upload/FileUpload.tsx
+++ b/src/components/common/file-upload/FileUpload.tsx
@@ -5,21 +5,38 @@ const Input = styled('input')({
display: 'none',
})
+const mimeAllowlistStr = [
+ 'text/plain',
+ 'application/json',
+ 'application/pdf',
+ 'image/png',
+ 'image/jpeg',
+ 'application/xml',
+ 'text/xml',
+ 'application/msword',
+ 'application/vnd.ms-excel',
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+].join(',')
+
function FileUpload({
onUpload,
buttonLabel,
+ accept,
...rest
}: {
onUpload: (files: File[]) => void
buttonLabel: string
- accept?: string
+ accept?: string[]
}) {
+ const acceptStr = accept ? accept.join(',') : mimeAllowlistStr
+
return (