diff --git a/src/components/form/FileUpload.tsx b/src/components/form/FileUpload.tsx index f6c79d7..5f1c531 100644 --- a/src/components/form/FileUpload.tsx +++ b/src/components/form/FileUpload.tsx @@ -1,22 +1,22 @@ import React, { useState, ChangeEvent, DragEvent } from "react"; interface FileUploadProps { + files: File[]; onFileChange: (files: File[]) => void; + multiple?: boolean; } -const FileUpload = (props: FileUploadProps) => { - const [files, setFiles] = useState([]); - +const FileUpload = ({ files, onFileChange, multiple = true }: FileUploadProps) => { const handleFileChange = (event: ChangeEvent) => { const newFiles = Array.from(event.target.files || []); - props.onFileChange([...files, ...newFiles]); - setFiles((prevFiles) => [...prevFiles, ...newFiles]); + onFileChange([...files, ...newFiles]); + event.target.value = ""; }; const handleDrop = (event: DragEvent) => { event.preventDefault(); const newFiles = Array.from(event.dataTransfer.files); - setFiles((prevFiles) => [...prevFiles, ...newFiles]); + onFileChange([...files, ...newFiles]); }; const handleDragOver = (event: DragEvent) => { @@ -24,8 +24,7 @@ const FileUpload = (props: FileUploadProps) => { }; const removeFile = (index: number) => { - props.onFileChange(files.filter((_, i) => i !== index)); - setFiles((prevFiles) => prevFiles.filter((_, i) => i !== index)); + onFileChange(files.filter((_, i) => i !== index)); }; return ( diff --git a/src/pages/ReceiptPage.tsx b/src/pages/ReceiptPage.tsx index 0054666..03f8bc9 100644 --- a/src/pages/ReceiptPage.tsx +++ b/src/pages/ReceiptPage.tsx @@ -50,8 +50,12 @@ const ReceiptPage = () => { const [usedOnlineCard, setUsedOnlineCard] = useState(false); const [disableSubmit, setDisableSubmit] = useState(false); + const [amountInput, setAmountInput] = useState(""); + const [accountNumber, setAccountNumber] = useState(""); + const [cardNumber, setCardNumber] = useState(""); const [attachments, setAttachments] = useState([]); + const allowedTypes = ["application/pdf", "image/png", "image/jpeg", "image/jpg"]; const auth = useAuth(); const { user } = auth; @@ -63,7 +67,16 @@ const ReceiptPage = () => { }); const onFileChange = async (files: File[]) => { - setAttachments([...files]); + const validFiles = files.filter((file) => allowedTypes.includes(file.type)); + const invalidFiles = files.filter((file) => !allowedTypes.includes(file.type)); + + if (invalidFiles.length > 0) { + alert("Bare PDF eller bildefiler (JPG, PNG, JPEG) er tillatt. Ugyldige filer ble ignorert."); + } + + if (validFiles.length > 0) { + setAttachments(validFiles); + } }; const [formdata, setFormdata]: [FormData, any] = useState({ @@ -76,8 +89,90 @@ const ReceiptPage = () => { account_number: "", }); + const [errors, setErrors] = useState({ + amount: "", + account_number: "", + card_number: "", + name: "", + committee_id: "", + attachments: "", + }); + + const validateForm = () => { + const newErrors: typeof errors = { + amount: "", + account_number: "", + card_number: "", + name: "", + committee_id: "", + attachments: "", + }; + + if (!amountInput) { + newErrors.amount = "Beløp må fylles inn"; + } else { + const num = Number(amountInput); + if (num <= 0) { + newErrors.amount = "Beløp må være større enn 0"; + } else if (num > 100000) { + newErrors.amount = "Beløp kan ikke overstige 100 000"; + } + } + + if (!usedOnlineCard) { + if (!/^\d{11}$/.test(formdata.account_number || "")) { + newErrors.account_number = "Kontonummer må være 11 sifre"; + } + } + + if (usedOnlineCard) { + const cardNumber = formdata.card_number || ""; + if (!/^\d{16}$/.test(cardNumber)) { + newErrors.card_number = "Kortnummer må være 16 sifre"; + } + } + + if (formdata.name.trim() === "") { + newErrors.name = "Vennligst skriv anledning"; + } + + if (!formdata.committee_id) { + newErrors.committee_id = "Velg en ansvarlig enhet"; + } + + if (attachments.length === 0) { + newErrors.attachments = "Last opp minst én kvittering/vedlegg"; + } + + setErrors(newErrors); + + return Object.values(newErrors).every((e) => e === ""); + }; + + const formatAccountNumber = (value: string) => { + const digits = value.replace(/\D/g, ""); + const parts: string[] = []; + + if (digits.length > 0) parts.push(digits.substring(0, 4)); + if (digits.length > 4) parts.push(digits.substring(4, 6)); + if (digits.length > 6) parts.push(digits.substring(6, 11)); + + return parts.join(" "); + }; + + const formatCardNumber = (value: string) => { + return value + .replace(/\D/g, "") + .replace(/(.{4})/g, "$1 ") + .trim(); + }; const submitform = async () => { + if (!validateForm()) return; + + const numericAmount = parseFloat(amountInput); + const updatedFormData = { ...formdata, amount: numericAmount }; + setDisableSubmit(true); const paymentInfo: PaymentInformation = { usedOnlineCard: usedOnlineCard, @@ -92,7 +187,7 @@ const ReceiptPage = () => { id: 0, }; const body: ReceiptRequestBody = { - receipt: formdata, + receipt: updatedFormData, attachments: await Promise.all( [...attachments].map(async (file) => await fileToBase64(file)), ), @@ -100,14 +195,12 @@ const ReceiptPage = () => { }; try { - await submitReceipt(body); - alert("Kvittering sendt inn!"); - // TODO: Fix with popup success message in home something - navigate("/?receiptsubmittedsuccess=1"); + await submitReceipt(body); + alert("Kvittering sendt inn!"); + // TODO: Fix with popup success message in home something + navigate("/?receiptsubmittedsuccess=1"); } catch (e) { - alert("Noe gikk galt, prøv igjen senere"); - } setDisableSubmit(false); @@ -161,25 +254,33 @@ const ReceiptPage = () => {

Kontonummer

{ - setFormdata({ ...formdata, account_number: e.target.value }); + const raw = e.target.value.replace(/\D/g, ""); + setAccountNumber(raw); + setFormdata({ ...formdata, account_number: raw }); }} > +

+ {errors.account_number || " "} +

Beløp

{ - setFormdata({ - ...formdata, - amount: parseInt(e.target.value), - }); - }} + max={100000} + onChange={(e) => setAmountInput(e.target.value)} > +

+ {errors.amount || " "} +

@@ -192,6 +293,9 @@ const ReceiptPage = () => { setFormdata({ ...formdata, name: e.target.value }); }} > +

+ {errors.name || " "} +

Ansvarlig enhet

@@ -215,33 +319,44 @@ const ReceiptPage = () => { }) : null} +

+ {errors.committee_id || " "} +

-

Kortinformasjon

+

Kortnummer

{ - setFormdata({ ...formdata, card_number: e.target.value }); + const raw = e.target.value.replace(/\D/g, ""); + setCardNumber(raw); + setFormdata({ ...formdata, card_number: raw }); }} - > + /> +

+ {errors.card_number || " "} +

Beløp

{ - setFormdata({ - ...formdata, - amount: parseInt(e.target.value), - }); - }} + max={100000} + onChange={(e) => setAmountInput(e.target.value)} > +

+ {errors.amount || " "} +

@@ -254,6 +369,9 @@ const ReceiptPage = () => { setFormdata({ ...formdata, name: e.target.value }); }} > +

+ {errors.name || " "} +

Ansvarlig enhet

@@ -267,7 +385,7 @@ const ReceiptPage = () => { }); }} > - + {data && data.length ? data.map((committee: any) => { return ( @@ -278,6 +396,9 @@ const ReceiptPage = () => { }) : null} +

+ {errors.committee_id || " "} +

@@ -296,7 +417,13 @@ const ReceiptPage = () => {

Vedlegg

- + +

+ {errors.attachments || " "} +