From 4dc0300f0770fc82fdbb17582dec2a80ff2c5016 Mon Sep 17 00:00:00 2001 From: Jaka Daneu <44704999+jalezi@users.noreply.github.com> Date: Thu, 29 Feb 2024 22:02:25 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=9A=B8=20adds=20confirmation=20di?= =?UTF-8?q?alog=20before=20user=20sends=20error=20report=20(#449)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 🚸 adds confirmation dialog before user sends error report * fix: 🩹 wrong texts * Update src/locales/en.json Co-authored-by: Štefan Baebler * Update Italian translation for error reporting confirmation dialog. Until proper translation we eill display in English. * Update src/locales/it.json Co-authored-by: Štefan Baebler * Update src/components/DoctorCard/ReportError/index.js Co-authored-by: Štefan Baebler * fix: 🐛 no formData Includes major refactoring. * feat: ✨ adds better user experience if error happens * fix: 💄 form has no padding * feat: 🚸 Add required attribute to form inputs and implement reset functionality --------- Co-authored-by: Štefan Baebler --- src/components/DoctorCard/PageInfo/index.js | 12 +- .../DoctorCard/ReportError/InlineEdit.js | 120 ++++--- .../DoctorCard/ReportError/index.js | 323 ++++++++++-------- .../ReportError/styles/InlineEdit.js | 16 + .../DoctorCard/ReportError/useInputs.js | 58 ++++ .../DoctorCard/ReportError/utils.js | 153 +++++++++ src/locales/en.json | 8 + src/locales/it.json | 2 +- src/locales/sl.json | 8 + 9 files changed, 496 insertions(+), 204 deletions(-) create mode 100644 src/components/DoctorCard/ReportError/useInputs.js create mode 100644 src/components/DoctorCard/ReportError/utils.js diff --git a/src/components/DoctorCard/PageInfo/index.js b/src/components/DoctorCard/PageInfo/index.js index 4ded69b9..ea0a9e17 100644 --- a/src/components/DoctorCard/PageInfo/index.js +++ b/src/components/DoctorCard/PageInfo/index.js @@ -45,6 +45,7 @@ const PageInfo = function PageInfo({ doctor }) { const [isEditing, setIsEditing] = useState(isReportError); const [message, setMessage] = useState(''); + const [isError, setIsError] = useState(false); const reportError = () => { setIsEditing(true); @@ -71,6 +72,8 @@ const PageInfo = function PageInfo({ doctor }) { doctorFormData={doctorFormData} setIsEditing={setIsEditing} setMessage={setMessage} + isError={isError} + setIsError={setIsError} /> ); } @@ -125,11 +128,16 @@ const PageInfo = function PageInfo({ doctor }) { - {message && ( + {!isError && message ? ( {message} - )} + ) : null} + {isError && message ? ( + + {message} + + ) : null} {doctor.website && } {doctor.phone && } diff --git a/src/components/DoctorCard/ReportError/InlineEdit.js b/src/components/DoctorCard/ReportError/InlineEdit.js index 6b552238..3f5ac64e 100644 --- a/src/components/DoctorCard/ReportError/InlineEdit.js +++ b/src/components/DoctorCard/ReportError/InlineEdit.js @@ -1,13 +1,20 @@ import PropTypes from 'prop-types'; import { t } from 'i18next'; -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import * as Styled from './styles'; -export const TextareaEdit = function TextareaEdit({ name, value, setValue, placeholder }) { - const [editingValue, setEditingValue] = useState(value); - - const onChange = event => setEditingValue(event.target.value); +export const TextareaEdit = function TextareaEdit({ + name, + value, + setValue, + placeholder, + id, + label, + required = undefined, +}) { + const onChange = event => setValue(event.target.value); + const onBlur = event => setValue(event.target.value); const onKeyDown = event => { if (event.key === 'Enter' || event.key === 'Escape') { @@ -15,14 +22,6 @@ export const TextareaEdit = function TextareaEdit({ name, value, setValue, place } }; - const onBlur = event => { - if (event.target.value.trim() === '') { - setEditingValue(value); - } else { - setValue(event.target.value); - } - }; - const textareaRef = useRef(); const height = textareaRef.current?.scrollHeight; @@ -34,30 +33,40 @@ export const TextareaEdit = function TextareaEdit({ name, value, setValue, place }, [height]); return ( - + + {label || name} + + ); }; -export const SelectEdit = function SelectEdit({ name, value, setValue }) { +export const SelectEdit = function SelectEdit({ + name, + value, + setValue, + label, + id, + required = undefined, +}) { const values = [ // csv file has values "y" and "n" { k: 'n', v: t('rejects').toUpperCase() }, { k: 'y', v: t('accepts').toUpperCase() }, ]; - const [editingValue, setEditingValue] = useState(value); - - const onChange = event => setEditingValue(event.target.value); + const onChange = event => setValue(event.target.value); + const onBlur = event => setValue(event.target.value); const onKeyDown = event => { if (event.key === 'Enter' || event.key === 'Escape') { @@ -65,35 +74,33 @@ export const SelectEdit = function SelectEdit({ name, value, setValue }) { } }; - const onBlur = event => { - if (event.target.value.trim() === '') { - setEditingValue(value); - } else { - setValue(event.target.value); - } - }; - return ( - - {values.map(({ k, v }) => ( - - ))} - + + {label || name} + + {values.map(({ k, v }) => ( + + ))} + + ); }; TextareaEdit.defaultProps = { placeholder: 'placeholder', + label: '', + required: undefined, }; TextareaEdit.propTypes = { @@ -101,10 +108,21 @@ TextareaEdit.propTypes = { value: PropTypes.string.isRequired, setValue: PropTypes.func.isRequired, placeholder: PropTypes.string, + label: PropTypes.string, + id: PropTypes.string.isRequired, + required: true || undefined, +}; + +SelectEdit.defaultProps = { + label: '', + required: undefined, }; SelectEdit.propTypes = { name: PropTypes.string.isRequired, value: PropTypes.string.isRequired, setValue: PropTypes.func.isRequired, + label: PropTypes.string, + id: PropTypes.string.isRequired, + required: true || undefined, }; diff --git a/src/components/DoctorCard/ReportError/index.js b/src/components/DoctorCard/ReportError/index.js index 958f1d8f..e2f2bded 100644 --- a/src/components/DoctorCard/ReportError/index.js +++ b/src/components/DoctorCard/ReportError/index.js @@ -1,7 +1,18 @@ -import { useState } from 'react'; +import { useRef, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import PropTypes from 'prop-types'; -import { CardContent, Typography, Stack, Button, Alert } from '@mui/material'; +import { + CardContent, + Typography, + Stack, + Button, + Alert, + Dialog, + DialogTitle, + DialogActions, + DialogContent, + DialogContentText, +} from '@mui/material'; import { t } from 'i18next'; import * as SEO from 'components/SEO'; @@ -9,13 +20,24 @@ import slugify from 'slugify'; import * as Shared from '../Shared'; import { SelectEdit, TextareaEdit } from './InlineEdit'; import { toPercent } from '../utils'; +import { HIDDEN_FIELDS, getChangedValue, getGSheetFormUrl, makeInputNames } from './utils'; +import { useInputs } from './useInputs'; -const ReportError = function ReportError({ doctorFormData, setIsEditing, setMessage }) { +const ReportError = function ReportError({ + doctorFormData, + setIsEditing, + setMessage, + isError, + setIsError, +}) { const { lng } = useParams(); const navigate = useNavigate(); + const [openDialog, setOpenDialog] = useState(false); + const formRef = useRef(); + const meta = [{ name: 'robots', content: 'noindex' }]; - const accepts = doctorFormData.accepts === 'y'; + const isAccepting = doctorFormData.accepts === 'y'; const [type, ageGroup] = doctorFormData.type.split('-'); const availabilityText = toPercent(doctorFormData.availability, lng); @@ -24,117 +46,23 @@ const ReportError = function ReportError({ doctorFormData, setIsEditing, setMess const { instId } = doctorFormData; const path = `/${lng}/${drPath}/${slug}/${instId}`; - const [inputAddress, setInputAddress] = useState(doctorFormData.fullAddress); - const [inputAccepts, setInputAccepts] = useState(accepts ? 'y' : 'n'); - const [inputAvailability, setInputAvailability] = useState(availabilityText); - const [inputPhone, setInputPhone] = useState(doctorFormData.phone); - const [inputWebsite, setInputWebsite] = useState(doctorFormData.website); - const [inputEmail, setInputEmail] = useState(doctorFormData.email); - const [inputOrderform, setInputOrderform] = useState(doctorFormData.orderform); - const [inputNote, setInputNote] = useState(doctorFormData.note); - - const formUrl = `https://docs.google.com/forms/d/${process.env.REACT_APP_GOOGLE_FORM_ID}/formResponse`; - - const formState = { - inputName: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_NAME, - value: doctorFormData.name, - }, - inputUrl: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_URL, - value: process.env.REACT_APP_URL + path, - }, - inputType: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_TYPE, - value: doctorFormData.type, - }, - inputInstId: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_INSTID, - value: doctorFormData.instId, - }, - inputProvider: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_PROVIDER, - value: doctorFormData.provider, - }, - inputFullAddress: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_ADDRESS, - value: inputAddress, - }, - inputAccepts: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_ACCEPTS, - value: inputAccepts, - }, - inputAvailability: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_AVAILABILITY, - value: inputAvailability, - }, - inputWebsite: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_WEBSITE, - value: inputWebsite, - }, - inputPhone: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_PHONE, - value: inputPhone, - }, - inputEmail: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_EMAIL, - value: inputEmail, - }, - inputOrderform: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_ORDERFORM, - value: inputOrderform, - }, - inputNote: { - id: process.env.REACT_APP_GOOGLE_FORM_INPUT_NOTE, - value: inputNote, - }, + /** @type {import('./useInputs.jsx').InitialValues} */ + const initialValues = { + address: doctorFormData.fullAddress, + accepts: isAccepting ? 'y' : 'n', + availability: availabilityText, + phone: doctorFormData.phone, + website: doctorFormData.website, + email: doctorFormData.email, + orderform: doctorFormData.orderform, + note: doctorFormData.note, }; - const submit = async e => { - e.preventDefault(); + const inputs = useInputs(initialValues); + const getIsSame = () => Object.keys(inputs).every(key => inputs[key][0] === initialValues[key]); - // if none of the input data is changed, do not send anything to Google Sheets - if ( - inputAddress === doctorFormData.fullAddress && - inputAccepts === doctorFormData.accepts && - inputAvailability === availabilityText && - inputWebsite === doctorFormData.website && - inputPhone === doctorFormData.phone && - inputEmail === doctorFormData.email && - inputOrderform === doctorFormData.orderform && - inputNote === doctorFormData.note - ) { - return; - } - - // if any input data is not changed, do not send it to Google Sheets - if (inputAddress === doctorFormData.fullAddress) { - formState.inputFullAddress.value = ''; - } - if (inputAccepts === doctorFormData.accepts) { - formState.inputAccepts.value = ''; - } - if (inputAvailability === availabilityText) { - formState.inputAvailability.value = ''; - } - if (inputWebsite === doctorFormData.website) { - formState.inputWebsite.value = ''; - } - if (inputPhone === doctorFormData.phone) { - formState.inputPhone.value = ''; - } - if (inputEmail === doctorFormData.email) { - formState.inputEmail.value = ''; - } - if (inputOrderform === doctorFormData.orderform) { - formState.inputOrderform.value = ''; - } - if (inputNote === doctorFormData.note) { - formState.inputNote.value = ''; - } - - const formData = new FormData(); - Object.values(formState).forEach(item => formData.append(`entry.${item.id}`, item.value)); + const postForm = async formData => { + const formUrl = getGSheetFormUrl(); try { await fetch(formUrl, { @@ -151,36 +79,93 @@ const ReportError = function ReportError({ doctorFormData, setIsEditing, setMess }); setMessage(t('reportError.reportReceived')); } catch (err) { - setMessage('Error:', err); + setIsError(true); + setMessage(t('reportError.reportError')); } finally { + setOpenDialog(false); + setIsEditing(false); + if (isError) { + setTimeout(() => { + setIsError(false); + }, 5000); + } + setTimeout(() => { + setMessage(''); + }, 5000); + } + }; + + const submit = e => { + e.preventDefault(); + const isSame = getIsSame(); + if (isSame) { + setMessage(t('reportError.reportNoChange')); setIsEditing(false); setTimeout(() => { setMessage(''); }, 5000); + return; } + setOpenDialog(true); + }; + + const resetInputs = () => { + inputs.address[1](initialValues.address); + inputs.accepts[1](initialValues.accepts); + inputs.availability[1](initialValues.availability); + inputs.phone[1](initialValues.phone); + inputs.website[1](initialValues.website); + inputs.email[1](initialValues.email); + inputs.orderform[1](initialValues.orderform); + inputs.note[1](initialValues.note); }; const resetForm = () => { setIsEditing(false); setMessage(''); - setInputAddress(doctorFormData.fullAddress); - setInputAccepts(accepts.toString()); - setInputAvailability(doctorFormData.availabilityText); - setInputPhone(doctorFormData.phone); - setInputWebsite(doctorFormData.website); - setInputEmail(doctorFormData.email); - setInputOrderform(doctorFormData.orderform); - setInputNote(doctorFormData.note); + if (isError) { + setIsError(false); + } + resetInputs(); navigate(path); }; + const handleOK = async () => { + const currentFormData = new FormData(formRef.current); + const formData = new FormData(); + const inputNames = makeInputNames(); + const hiddenInputNames = Object.entries(inputNames).filter(([key]) => + HIDDEN_FIELDS.includes(key), + ); + const visibleInputNames = Object.entries(inputNames).filter( + ([key]) => !HIDDEN_FIELDS.includes(key), + ); + + hiddenInputNames.forEach(([key, value]) => { + formData.set(value, currentFormData.get(key)); + }); + + visibleInputNames.forEach(([key, value]) => { + const changedValue = getChangedValue(inputs[key][0], initialValues[key]); + if (typeof changedValue === 'string') { + formData.set(value, changedValue); + } + }); + + await postForm(formData); + }; + + const handleCancel = () => { + setOpenDialog(false); + }; + return ( <> -
+
{doctorFormData.name} @@ -191,60 +176,96 @@ const ReportError = function ReportError({ doctorFormData, setIsEditing, setMess {t('reportError.text')} + + + + + + - + -
- - + + + + + +
+ + {t('reportError.confirmation.title')} + + {t('reportError.confirmation.warningText')} + + {t('reportError.confirmation.text')} + + + + + - - - + + ); }; @@ -267,5 +288,7 @@ ReportError.propTypes = { }).isRequired, setIsEditing: PropTypes.func.isRequired, setMessage: PropTypes.func.isRequired, + isError: PropTypes.bool.isRequired, + setIsError: PropTypes.func.isRequired, }; export default ReportError; diff --git a/src/components/DoctorCard/ReportError/styles/InlineEdit.js b/src/components/DoctorCard/ReportError/styles/InlineEdit.js index 229ecdc8..0f0fb06c 100644 --- a/src/components/DoctorCard/ReportError/styles/InlineEdit.js +++ b/src/components/DoctorCard/ReportError/styles/InlineEdit.js @@ -1,5 +1,21 @@ import { styled } from '@mui/material/styles'; +export const Wrapper = styled('div')` + position: relative; +`; + +export const LabelSrOnly = styled('label')` + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +`; + export const Textarea = styled('textarea')(({ theme }) => ({ fontFamily: '"IBM Plex Sans", sans-serif', fontSize: '0.8rem', diff --git a/src/components/DoctorCard/ReportError/useInputs.js b/src/components/DoctorCard/ReportError/useInputs.js new file mode 100644 index 00000000..3593e402 --- /dev/null +++ b/src/components/DoctorCard/ReportError/useInputs.js @@ -0,0 +1,58 @@ +const { useState } = require('react'); +// not sure if this is the best way to do this +/** + * Add this type in top of your file, or if commonly used in some types file. + * @template T + * @typedef {[T, import('react').Dispatch>]} useState + */ + +/** + * @typedef {Object} Inputs + * @property {string} address - The address input value. + * @property {string} accepts - The accepts input value. + * @property {string} availability - The availability input value. + * @property {string} phone - The phone input value. + * @property {string} website - The website input value. + * @property {string} email - The email input value. + * @property {string} orderform - The orderform input value. + * @property {string} note - The note input value. + */ + +/** + * @typedef {Inputs} InitialValues + */ + +/** + * Custom hook for managing input values. + * + * @param {InitialValues} initialValues - The initial values for the inputs. + */ +export function useInputs(initialValues) { + /** @type useState */ + const [inputAddress, setInputAddress] = useState(initialValues.address); + /** @type useState */ + const [inputAccepts, setInputAccepts] = useState(initialValues.accepts); + /** @type useState */ + const [inputAvailability, setInputAvailability] = useState(initialValues.availability); + /** @type useState */ + const [inputPhone, setInputPhone] = useState(initialValues.phone); + /** @type useState */ + const [inputWebsite, setInputWebsite] = useState(initialValues.website); + /** @type useState */ + const [inputEmail, setInputEmail] = useState(initialValues.email); + /** @type useState */ + const [inputOrderform, setInputOrderform] = useState(initialValues.orderform); + /** @type useState */ + const [inputNote, setInputNote] = useState(initialValues.note); + + return { + address: [inputAddress, setInputAddress], + accepts: [inputAccepts, setInputAccepts], + availability: [inputAvailability, setInputAvailability], + phone: [inputPhone, setInputPhone], + website: [inputWebsite, setInputWebsite], + email: [inputEmail, setInputEmail], + orderform: [inputOrderform, setInputOrderform], + note: [inputNote, setInputNote], + }; +} diff --git a/src/components/DoctorCard/ReportError/utils.js b/src/components/DoctorCard/ReportError/utils.js new file mode 100644 index 00000000..014d9fcc --- /dev/null +++ b/src/components/DoctorCard/ReportError/utils.js @@ -0,0 +1,153 @@ +/** + * Object containing the form field IDs. + * @typedef {Object} FormFieldIds + * @property {string} name - The ID for the input field representing the name. + * @property {string} url - The ID for the input field representing the URL. + * @property {string} type - The ID for the input field representing the type. + * @property {string} instId - The ID for the input field representing the institution ID. + * @property {string} provider - The ID for the input field representing the provider. + * @property {string} address - The ID for the input field representing the full address. + * @property {string} accepts - The ID for the input field representing the accepts field. + * @property {string} availability - The ID for the input field representing the availability. + * @property {string} website - The ID for the input field representing the website. + * @property {string} phone - The ID for the input field representing the phone number. + * @property {string} email - The ID for the input field representing the email. + * @property {string} orderform - The ID for the input field representing the order form. + * @property {string} note - The ID for the input field representing the note. + */ + +/** + * An array of the hidden form field names. + * @constant {string[]} - An array of the hidden form field names. + * @default + */ +export const HIDDEN_FIELDS = ['name', 'url', 'type', 'instId', 'provider']; + +/** + * Retrieves the Google Sheet form field IDs. + * @returns {FormFieldIds} The form field IDs. + */ +export function getGSheetFormFieldIds() { + return { + name: process.env.REACT_APP_GOOGLE_FORM_INPUT_NAME, + url: process.env.REACT_APP_GOOGLE_FORM_INPUT_URL, + type: process.env.REACT_APP_GOOGLE_FORM_INPUT_TYPE, + instId: process.env.REACT_APP_GOOGLE_FORM_INPUT_INSTID, + provider: process.env.REACT_APP_GOOGLE_FORM_INPUT_PROVIDER, + address: process.env.REACT_APP_GOOGLE_FORM_INPUT_ADDRESS, + accepts: process.env.REACT_APP_GOOGLE_FORM_INPUT_ACCEPTS, + availability: process.env.REACT_APP_GOOGLE_FORM_INPUT_AVAILABILITY, + website: process.env.REACT_APP_GOOGLE_FORM_INPUT_WEBSITE, + phone: process.env.REACT_APP_GOOGLE_FORM_INPUT_PHONE, + email: process.env.REACT_APP_GOOGLE_FORM_INPUT_EMAIL, + orderform: process.env.REACT_APP_GOOGLE_FORM_INPUT_ORDERFORM, + note: process.env.REACT_APP_GOOGLE_FORM_INPUT_NOTE, + }; +} + +/** + * Retrieves the Google Sheet form URL. + * @returns {string} The form URL. + * + * */ +export function getGSheetFormUrl() { + return `https://docs.google.com/forms/d/${process.env.REACT_APP_GOOGLE_FORM_ID}/formResponse`; +} + +/** + * Generates form field names with an optional prefix. + * + * @param {string} appended [appended = "entry."] - The prefix to be appended to each form field name. + * @returns {FormFieldIds} - An object containing form field names. + */ +export function makeInputNames(appended = 'entry.') { + /** + * @type {FormFieldIds} - An object containing form field names. + */ + const obj = {}; + const formFieldIds = getGSheetFormFieldIds(); + + return Object.keys(formFieldIds).reduce((acc, key) => { + acc[key] = appended + formFieldIds[key]; + return acc; + }, obj); +} + +/** + * Checks if the input value has changed from the initial value. + * @param {string} input - The input value to check. + * @param {string} initialValue - The initial value to compare against. + * @returns {string} - An empty string if the input value is equal to the initial value, otherwise the input value. + */ +export function getChangedValue(input, initialValue) { + return input === initialValue ? '' : input; +} + +/** + * Checks if the input value has changed from the initial value. + * + * @param {string} input - The current input value. + * @param {string} initialValue - The initial value. + * @returns {boolean} - True if the input value has changed, false otherwise. + */ +export function isValueChanged(input, initialValue) { + return input !== initialValue; +} + +// FIXME - some properties are missing +/** + * Doctor object. + * + * @typedef {Object} Doctor + * @property {string} name - The name of the doctor. + * @property {string} url - The URL of the doctor. + * @property {string} type - The type of the doctor. + * @property {string} instId - The institution ID of the doctor. + * @property {string} provider - The provider of the doctor. + * @property {string} fullAddress - The full address of the doctor. + * @property {string} accepts - The accepts field of the doctor. + * @property {string} availability - The availability of the doctor. + * @property {string} website - The website of the doctor. + * @property {string} phone - The phone number of the doctor. + * @property {string} email - The email of the doctor. + * @property {string} orderform - The order form of the doctor. + * @property {string} note - The note of the doctor. + * @property {string} [message] - The message to display after submitting the form. + */ + +/** + * @typedef {Object} HiddenFields + * @property {string} name - The name of the doctor. + * @property {string} url - The URL of the doctor. + * @property {string} type - The type of the doctor. + * @property {string} instId - The institution ID of the doctor. + * @property {string} provider - The provider of the doctor. + */ + +/** + * Returns an object containing the hidden values of a doctor. + * + * @param {Doctor} doctor - The doctor object.The provider of the doctor. + * @returns {HiddenFields} - An object containing the hidden values. + */ +export function getHiddenValues(doctor) { + return { + name: doctor.name, + url: doctor.url, + type: doctor.type, + instId: doctor.instId, + provider: doctor.provider, + }; +} + +/** + * Flips the key-value pairs of an object. + * @param {Object.} obj - The object to flip. + * @returns {Object.} - The flipped object. + */ +export function flipKeyValue(obj) { + return Object.keys(obj).reduce((acc, key) => { + acc[obj[key]] = key; + return acc; + }, {}); +} diff --git a/src/locales/en.json b/src/locales/en.json index ef16f403..8cb295a3 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -68,7 +68,10 @@ "text": "Report error in doctor data and add the correct data or notes:", "cancel": "Cancel", "send": "Send", + "reset": "Reset", "reportReceived": "Thank you! We will look into it.", + "reportError": "Error reporting failed. Please try again later.", + "reportNoChange": "No data has been changed", "placeholder": { "address": "address", "website": "web page", @@ -77,6 +80,11 @@ "orderform": "link to order page", "availability": "availability", "note": "note" + }, + "confirmation": { + "title": "Confirm", + "warningText": "This form is NOT intended to request an appointment for medical examination or consultation. To make an appointment, contact your chosen doctor.", + "text": "Are you sure you want to suggest a data update?" } }, "error": { diff --git a/src/locales/it.json b/src/locales/it.json index 293829c8..d9e7e32f 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -91,4 +91,4 @@ "error": { "title": "Qualcosa è andato storto" } -} +} \ No newline at end of file diff --git a/src/locales/sl.json b/src/locales/sl.json index c0ae107c..24d92943 100644 --- a/src/locales/sl.json +++ b/src/locales/sl.json @@ -70,7 +70,10 @@ "text": "Prijavi napako na posameznih podatkih o zdravniku in vnesi pravilne podatke ali opombo:", "cancel": "Prekliči", "send": "Pošlji", + "reset": "Ponastavi", "reportReceived": "Hvala za poslano! Podatke bomo pregledali.", + "reportError": "Prišlo je do napake pri pošiljanju podatkov. Prosim, poskusite znova.", + "reportNoChange": "Noben podatek ni bil spremenjen.", "placeholder": { "address": "naslov", "website": "spletna stran", @@ -79,6 +82,11 @@ "orderform": "povezava za naročanje", "availability": "obseg zaposlitve", "note": "opomba" + }, + "confirmation": { + "title": "Potrditev", + "warningText": "Obrazec NI namenjen naročanju na pregled ali posvet. Za naročanje se obrnite na izbranega zdravnika.", + "text": "Ali ste prepričani, da želite predlagati popravek podatkov?" } }, "error": {