From a133a637502bd15d1529b20e5b1631c74d228aab Mon Sep 17 00:00:00 2001 From: Tudor Amariei Date: Mon, 4 Mar 2024 13:53:41 +0200 Subject: [PATCH 1/4] Update labels and translations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - update the info property of the fields in the financial info overlay - fix some texts - update the raf label to use a placeholder - update "oraș" to "localitate" --- .../src/assets/locales/en/translation.json | 36 +++++------ .../src/assets/locales/ro/translation.json | 60 ++++++++++--------- .../OrganizationGeneralConfig.ts | 3 +- 3 files changed, 51 insertions(+), 48 deletions(-) diff --git a/frontend/src/assets/locales/en/translation.json b/frontend/src/assets/locales/en/translation.json index 5f0f12bc..55b3dd98 100644 --- a/frontend/src/assets/locales/en/translation.json +++ b/frontend/src/assets/locales/en/translation.json @@ -622,77 +622,77 @@ "income": { "membership": { "label": "Income from contributions", - "info": "Income from membership fees info" + "info": "The total income from the contributions of the association members, if applicable to your NGO." }, "donations": { "label": "Income from donations", - "info": "Income from donations info" + "info": "The total of individual donations you received in the previous year (either SMS or donation through crowdfunding platforms)." }, "percent": { "label": "Revenue from the redirection of 3.5% of income tax%", - "info": "Revenue from the redirection of 3.5% of income tax% info" + "info": "The total income obtained through the 230 forms sent to your organization." }, "sponsorship": { "label": "Sponsorship income", - "info": "Sponsorship income info" + "info": "The total income from sponsorships received from companies or obtained through grants or other donations from legal entities." }, "economic": { "label": "Income from economic activity", - "info": "Income from economic activity info" + "info": "The total income you obtained from service contracts, if applicable." }, "other": { "label": "Other income", - "info": "Other income info" + "info": "Enter here the total income obtained from other sources (for example, selling items at fairs)." }, "financial": { "label": "Financial income", - "info": "Financial income info" + "info": "The total income resulting from financial operations, for example the interest you get on deposits or exchange rate differences." } }, "expense": { "net": { "label": "Net salaries (human resources)", - "info": "Net salaries (human resources) info" + "info": "Your total expenses with the net salaries of your employees and contractors." }, "cas": { "label": "CAS contributions (human resources)", - "info": "CAS contributions (human resources) info" + "info": "The total taxes you paid to the state." }, "economic": { "label": "Direct expenditure from economic activity", - "info": "Direct expenditure from economic activity info" + "info": "The total amount spent on service contracts." }, "administrative": { "label": "Administrative expenditure", - "info": "Administrative expenditure info" + "info": "Your total expenses with rent, utilities and other services related to your headquarters." }, "transport": { "label": "Transport and accommodation", - "info": "Transport and accommodation info" + "info": "Total expenses with any type of transport and accommodation and per diem of your employees." }, "catering": { "label": "Catering", - "info": "Catering info" + "info": "Total expenses made in the previous year with the catering consumed at events or on other occasions." }, "production": { "label": "Production", - "info": "Production info" + "info": "Total expenses for producing your communication materials (for example stickers, roll-ups, flyers etc.)." }, "software": { "label": "Software services", - "info": "Software services info" + "info": "Total expenses with subscriptions to applications you use (for example Mailchimp, Google Drive etc.)." }, "advertising": { "label": "Advertising and publicity", - "info": "Advertising and publicity info" + "info": "Total expenses of the organization on communication campaigns, for example Facebook Ads or LinkedIn Ads." }, "taxes": { "label": "Other taxes", - "info": "Other tax info" + "info": "Total of any other taxes you paid in the previous year, for example VAT if applicable." }, "expense": { "label": "Other expenses", - "info": "Other expenses info" + "info": "Enter here the total of any other expenses you have not entered in other segments of this budget (for example the purchase of a trailer for a caravan etc.)." } } }, diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index 3d143701..fa474911 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -164,7 +164,8 @@ }, "list_item_5": "Organizația va menționa contribuția Asociației Code for Romania în activitatea sa acolo unde este cazul;", "list_item_6": "Asociația Code for Romania are dreptul să menționeze public asistența oferită organizației;", - "list_item_7": "Asociația Code for Romania își rezervă dreptul de restricționa accesul la NGO Hub a organizațiilor care nu respectă condițiile de mai sus;", "paragraph": "Continuarea procesului de înregistrare reprezintă declarația reprezentantului organizației că organizația pe care o reprezintă îndeplinește criteriile de eligibilitate menționate mai sus și este de acord cu clauzele.", + "list_item_7": "Asociația Code for Romania își rezervă dreptul de restricționa accesul la NGO Hub a organizațiilor care nu respectă condițiile de mai sus;", + "paragraph": "Continuarea procesului de înregistrare reprezintă declarația reprezentantului organizației că organizația pe care o reprezintă îndeplinește criteriile de eligibilitate menționate mai sus și este de acord cu clauzele.", "support_paragraph": "Dacă ai întrebări, ne poți scrie la: ", "terms_and_agreement_paragraph": "Am citit și sunt de acord cu criteriile menționate mai sus", "form": { @@ -307,11 +308,12 @@ "max": "Numărul RAF poate avea maxim 20 de caractere", "min": "Numărul RAF poate avea minim 8 caractere", "invalid": "Numărul RAF are un format invalid", - "label": "Număr de înregistrare în RAF*" + "label": "Număr de înregistrare în RAF*", + "placeholder": "56/14.09.2020" }, "city": { - "required": "Orașul este obligatoriu", - "label": "Oraș*" + "required": "Localitatea este obligatorie", + "label": "Localitate*" }, "county": { "required": "Județul este obligatoriu", @@ -328,7 +330,7 @@ "required": "Prezentarea este obligatorie", "max": "Prezentarea trebuie să aibă maxim 2000 de caractere", "min": "Prezentarea trebuie să aibă minim 500 de caractere", - "label": "Prezentare detaliată a organizație*", + "label": "Prezentare detaliată a organizației*", "helper": "Adaugă o prezentare mai detaliată a organizației. Această prezentare va fi afișată pe paginile de prezentare a organizației din ecosistemul NGO Hub. Prezentarea poate avea între 500 și 2000 de caractere." }, "contact": { @@ -388,7 +390,7 @@ "placeholder": "Adresa" }, "organization_city": { - "label": "Oraș" + "label": "Localitate" }, "organization_county": { "label": "Județ" @@ -623,77 +625,77 @@ "income": { "membership": { "label": "Venituri din cotizații", - "info": "Venituri din cotizații info" + "info": "Totalul veniturilor din cotizațiile membrilor asociației, dacă este cazul ONG-ului tău." }, "donations": { "label": "Venituri din donații", - "info": "Venituri din donații info" + "info": "Totalul donațiilor individuale pe care le-ai primit în anul precedent (fie SMS sau donație prin platforme de crowdfunding)." }, "percent": { - "label": "Venituri din redirecționarea a 3.5% din impozitul pe venit%", - "info": "Venituri din redirecționarea a 3.5% din impozitul pe venit% info" + "label": "Venituri din redirecționarea a 3.5% din impozitul pe venit", + "info": "Totalul veniturilor obținute prin formularele 230 trimise către organizația ta." }, "sponsorship": { "label": "Venituri din sponsorizări", - "info": "Venituri din sponsorizări info" + "info": "Totalul veniturilor din sponsorizările primite de la companii sau obținute prin granturi sau alte donații de la persoane juridice." }, "economic": { - "label": "Venituri din activitatea economica", - "info": "Venituri din activitatea economica info" + "label": "Venituri din activitatea economică", + "info": "Totalul veniturilor pe care le-ai obținut în urma contractelor de prestări servicii, dacă este cazul." }, "other": { "label": "Alte venituri", - "info": "Alte venituri info" + "info": "Introdu aici totalul veniturilor obținute din alte surse (de exemplu vânzarea de obiecte la târguri)." }, "financial": { "label": "Venituri financiare", - "info": "Venituri financiare info" + "info": "Totalul veniturilor care au rezultat in urma unor operațiuni financiare, de exemplu dobânda pe care o obții la depozite sau diferențele de schimb valutar." } }, "expense": { "net": { "label": "Salarii nete (resurse umane)", - "info": "Salarii nete (resurse umane) info" + "info": "Cheltuielile tale totale cu salariile nete ale angajaților și contractorilor tăi." }, "cas": { "label": "Contribuții CAS (resurse umane)", - "info": "Contribuții CAS (resurse umane) info" + "info": "Totalul taxelor pe care le-ai plătit către stat." }, "economic": { - "label": "Cheltuieli directe din activitatea economica", - "info": "Cheltuieli directe din activitatea economica info" + "label": "Cheltuieli directe din activitatea economică", + "info": "Totalul sumelor cheltuite pe contrate de prestări servicii." }, "administrative": { "label": "Cheltuieli administrative", - "info": "Cheltuieli administrative info" + "info": "Totalul cheltuielilor tale cu chiria, utilitățile și alte servicii care țin de sediul/sediile tale." }, "transport": { "label": "Transport și cazare", - "info": "Transport și cazare info" + "info": "Totalul cheltuielilor cu orice tip de transport și cazare și diurnele personalului tău angajat." }, "catering": { "label": "Catering", - "info": "Catering info" + "info": "Totalul cheltuielilor făcute în anul precedent cu catering-ul consumat la evenimente sau cu alte ocazii." }, "production": { "label": "Producție", - "info": "Producție info" + "info": "Totalul cheltuielilor de producere a materialelor tale de comunicare (de exemplu stickere, roll-upuri, flyere etc.)." }, "software": { "label": "Servicii software", - "info": "Servicii software info" + "info": "Totalul cheltuielilor cu abonamente la aplicații pe care le utilizezi (de exemplu Mailchimp, Google Drive etc.)." }, "advertising": { "label": "Reclame și publicitate", - "info": "Reclame și publicitate info" + "info": "Totalul cheltuielilor organizației pe campanii de comunicare, de exemplu Facebook Ads sau LinkedIn Ads." }, "taxes": { "label": "Alte taxe", - "info": "Alte taxe info" + "info": "Totalul oricăror alte taxe pe care le-ai plătit în anul precedent (de exemplu TVA, dacă a fost cazul)." }, "expense": { "label": "Alte cheltuieli", - "info": "Alte cheltuieli info" + "info": "Introduci aici totalul oricăror altor cheltuieli pe care nu le-ai trecut in alte segmente ale acestui buget (de exemplu achiziția unei rulote pentru o caravana etc.)." } } }, @@ -1451,8 +1453,8 @@ "placeholder": "Program de Practică" }, "location": { - "required": "Orașul este obligatoriu", - "label": "Oraș*", + "required": "Localitatea este obligatorie", + "label": "Localitate*", "helper": "Începe să scrii numele localității în câmpul de mai sus, apoi selectează-l pe cel dorit din listă", "placeholder": "Miercurea Ciuc" }, diff --git a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneralConfig.ts b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneralConfig.ts index 1ae51d1b..b6243779 100644 --- a/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneralConfig.ts +++ b/frontend/src/pages/organization/components/OrganizationGeneral/OrganizationGeneralConfig.ts @@ -68,6 +68,7 @@ const translations = { min: i18n.t('general:config.raf.min'), invalid: i18n.t('general:config.raf.invalid'), label: i18n.t('general:config.raf.label'), + placeholder: i18n.t('general:config.raf.placeholder'), }, city: { required: i18n.t('general:config.city.required'), @@ -363,7 +364,7 @@ export const OrganizationGeneralConfig: Record = { type: 'text', label: translations.raf.label, helperText: '', - placeholder: '', + placeholder: translations.raf.placeholder, }, }, city: { From 491f5dc4a48f4b8e5b07c42e8f403856b79cc076 Mon Sep 17 00:00:00 2001 From: Tudor Amariei Date: Mon, 4 Mar 2024 15:06:42 +0200 Subject: [PATCH 2/4] Update the translations to use "e-mail" instead of "email" --- .../src/assets/locales/en/translation.json | 82 +++++++++---------- .../src/assets/locales/ro/translation.json | 52 ++++++------ 2 files changed, 67 insertions(+), 67 deletions(-) diff --git a/frontend/src/assets/locales/en/translation.json b/frontend/src/assets/locales/en/translation.json index 55b3dd98..fc127175 100644 --- a/frontend/src/assets/locales/en/translation.json +++ b/frontend/src/assets/locales/en/translation.json @@ -107,7 +107,7 @@ "description": "Manage your organisation profile from here to access available applications.", "description_admin": "Manage your organisation profile from here to access available applications.", "description_request": "Manage your organisation profile from here to access available applications.", - "no_access": "Your organization has been restricted. For more details, contact our team free of charge by email at", + "no_access": "Your organization has been restricted. For more details, contact our team free of charge by e-mail at", "inactive": "Oops! Your organization is inactive.", "back": "Back to website", "send_mail": "Send E-Mail", @@ -137,7 +137,7 @@ }, "create": { "congratulations": "Congratulations", - "success": "You have successfully completed the NGO Hub application form. Confirmation of your application and a copy of the completed form have been sent to the email address indicated. We will verify your application and contact you as soon as possible to complete the NGO Hub implementation process for your organisation.", + "success": "You have successfully completed the NGO Hub application form. Confirmation of your application and a copy of the completed form have been sent to the e-mail address indicated. We will verify your application and contact you as soon as possible to complete the NGO Hub implementation process for your organisation.", "again": "Try again", "steps": { "first": "Step 1", @@ -174,14 +174,14 @@ } }, "errors": { - "REQ_001": "There is already a user with this email or phone number.", + "REQ_001": "There is already a user with this e-mail or phone number.", "REQ_007": "There is already an organisation with this CUI", "REQ_008": "There is already an organisation with this RAF", "REQ_009": "There is already an organisation with this name", "REQ_010": "There is already an organisation with this alias", - "REQ_011": "There is already an organisation with this email", + "REQ_011": "There is already an organisation with this e-mail", "REQ_012": "There is already an organisation with this phone number", - "REQ_002": "There is already an application with this email or phone number.", + "REQ_002": "There is already an application with this e-mail or phone number.", "ORG_026": "Error updating general data" } }, @@ -207,8 +207,8 @@ }, "email": { "required": "E-mail is required", - "max": "The email cannot be longer than 50 characters", - "invalid": "The email has an invalid format", + "max": "The e-mail cannot be longer than 50 characters", + "invalid": "The e-mail has an invalid format", "label": "E-mail" } }, @@ -242,7 +242,7 @@ }, "contact_information": { "title": "Informații de contact", - "subtitle": "These pieces of information will be made public on the organization's presentation pages on the various platforms included in NGO Hub (e.g., redirectioneaza.ro, where the organization's name, contact email, and website are displayed)." + "subtitle": "These pieces of information will be made public on the organization's presentation pages on the various platforms included in NGO Hub (e.g., redirectioneaza.ro, where the organization's name, contact e-mail, and website are displayed)." }, "communication_and_social_media": { "title": "Comunicare și social media", @@ -276,10 +276,10 @@ "helper": "" }, "email": { - "required": "Email is required", - "max": "The email can have a maximum of 250 characters", - "invalid": "The email has an invalid format.", - "label": "Organisation's contact email*", + "required": "E-mail is required", + "max": "The e-mail can have a maximum of 250 characters", + "invalid": "The e-mail has an invalid format.", + "label": "Organisation's contact e-mail*", "helper": "Example: contact@organizatie.ro" }, "phone": { @@ -339,10 +339,10 @@ "label": "Full name*" }, "contact_email": { - "required": "Contact email is required", - "max": "The contact email can have a maximum of 50 characters", - "invalid": "The contact email has an invalid format", - "label": "Email*" + "required": "Contact e-mail is required", + "max": "The contact e-mail can have a maximum of 50 characters", + "invalid": "The contact e-mail has an invalid format", + "label": "E-mail*" }, "contact_phone": { "required": "Phone number is required", @@ -520,7 +520,7 @@ "header": { "name": "Full name", "role": "Role", - "email": "Email", + "email": "E-mail", "phone": "Phone" }, "legal_config": { @@ -532,10 +532,10 @@ "label": "Full name*" }, "email": { - "required": "Email of the legal representative is required.", - "maxim": "The email of the legal representative cannot be longer than 50 characters.", - "invalid": "The email has an invalid format.", - "label": "Email*" + "required": "E-mail of the legal representative is required.", + "maxim": "The e-mail of the legal representative cannot be longer than 50 characters.", + "invalid": "The e-mail has an invalid format.", + "label": "E-mail*" }, "phone": { "required": "The telephone number of the legal representative is mandatory.", @@ -554,10 +554,10 @@ "label": "Full name*" }, "email": { - "required": "The email of the member of the Board of Directors is mandatory.", - "maxim": "The Governing Board member's email may not be longer than 50 characters.", - "invalid": "The Governing Board member's email has an invalid format.", - "label": "Email*" + "required": "The e-mail of the member of the Board of Directors is mandatory.", + "maxim": "The Governing Board member's e-mail may not be longer than 50 characters.", + "invalid": "The Governing Board member's e-mail has an invalid format.", + "label": "E-mail*" }, "phone": { "required": "The director's phone is invalid.", @@ -780,7 +780,7 @@ "subtitle": "Manage user accounts from here. You can add new users and edit or restrict existing users.", "add": "Add User", "not_found": "User does not exist in the database", - "failure_email": "There is already a user with this email", + "failure_email": "There is already a user with this e-mail", "failure_phone": "There is already a user with this phone number", "tabs": { "users": "Users", @@ -835,7 +835,7 @@ }, "list_header": { "name": "Name", - "email": "Email", + "email": "E-mail", "phone": "Phone", "status": "General access", "created": "Date added" @@ -859,10 +859,10 @@ "label": "Full name*" }, "email": { - "required": "Email is required", - "max": "The email can have a maximum of 50 characters", - "invalid": "The email has an invalid format", - "label": "Email*" + "required": "E-mail is required", + "max": "The e-mail can have a maximum of 50 characters", + "invalid": "The e-mail has an invalid format", + "label": "E-mail*" }, "phone": { "required": "Phone number is required", @@ -1077,10 +1077,10 @@ "delete": "Remove application", "contact": "We will contact you within 24-48 hours.", "active": "The app is active for your organisation.", - "define_active": "Lorem ipsum. What does it mean that the application is active. According to the needs of your NGO. A member of the Code for Romania team will contact you for further details as soon as possible on the contact email mentioned in your organization profile. Thank you.", + "define_active": "Lorem ipsum. What does it mean that the application is active. According to the needs of your NGO. A member of the Code for Romania team will contact you for further details as soon as possible on the contact e-mail mentioned in your organization profile. Thank you.", "open": "Open the app", "pending": "Your request is awaiting approval.", - "configure": "This application must be installed and configured according to the needs of your NGO. A member of the Code for Romania team will contact you for further details as soon as possible on the contact email mentioned in your organization profile. Thank you.", + "configure": "This application must be installed and configured according to the needs of your NGO. A member of the Code for Romania team will contact you for further details as soon as possible on the contact e-mail mentioned in your organization profile. Thank you.", "cancel": "Cancel request", "restore": "Contact us for a refund.", "close_button": "Remove application", @@ -1157,11 +1157,11 @@ "modals": { "approve": { "title": "Approve and send confirmation", - "description": "Following approval, the NGO will receive a confirmation email to the address provided at registration and a link to complete the process and gain access to the platform. Confirm approval?", + "description": "Following approval, the NGO will receive a confirmation e-mail to the address provided at registration and a link to complete the process and gain access to the platform. Confirm approval?", "confirm": "Yes, I approve the request" }, "reject": { - "title": "Reject and send email", + "title": "Reject and send e-mail", "description": "Following rejection, the NGO will receive a confirmation e-mail to the address provided upon registration. Confirm rejection?", "confirm": "Rejects the application" } @@ -1174,7 +1174,7 @@ "header": { "org_name": "Organisation", "name": "Name", - "email": "Email", + "email": "E-mail", "phone": "Phone", "status": "Status", "created_on": "Date added", @@ -1261,7 +1261,7 @@ "description": "TODO#14: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s" }, "email_or_phone": { - "title": "Access by email or phone", + "title": "Access by e-mail or phone", "description": "TODO#15: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s" }, "physical": { @@ -1359,16 +1359,16 @@ "label": "Phone*" }, "email": { - "required": "Email is required", - "max": "The email cannot be longer than 50 characters", - "pattern": "The email has an invalid format", + "required": "E-mail is required", + "max": "The e-mail cannot be longer than 50 characters", + "pattern": "The e-mail has an invalid format", "helper": "E-mail address where the applicant can request the service", "label": "E-mail*" }, "description": { "max": "The description cannot be longer than 1000 characters", "pattern": "The description is not in valid format.", - "label": "Email access description", + "label": "E-mail access description", "placeholder": "TODO#10: Lorem ipsum" } }, diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index fa474911..4839ed0d 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -277,9 +277,9 @@ "helper": "" }, "email": { - "required": "Email-ul este obligatoriu", - "max": "Email-ul poate avea maxim 250 de caractere", - "invalid": "Email-ul are un format invalid.", + "required": "E-mail-ul este obligatoriu", + "max": "E-mail-ul poate avea maxim 250 de caractere", + "invalid": "E-mail-ul are un format invalid.", "label": "E-mail-ul de contact al organizației*", "helper": "Exemplu: contact@organizatie.ro" }, @@ -341,10 +341,10 @@ "label": "Nume și prenume*" }, "contact_email": { - "required": "Email-ul contactului este obligatoriu", - "max": "Email-ul contactului poate avea maxim 50 de caractere", - "invalid": "Email-ul contactului are un format invalid", - "label": "Email*" + "required": "E-mail-ul contactului este obligatoriu", + "max": "E-mail-ul contactului poate avea maxim 50 de caractere", + "invalid": "E-mail-ul contactului are un format invalid", + "label": "E-mail*" }, "contact_phone": { "required": "Numărul de telefon este obligatoriu", @@ -523,7 +523,7 @@ "header": { "name": "Nume și prenume", "role": "Rol", - "email": "Email", + "email": "E-mail", "phone": "Telefon" }, "legal_config": { @@ -535,10 +535,10 @@ "label": "Nume și prenume*" }, "email": { - "required": "Email-ul reprezentantului legal este obligatoriu.", - "maxim": "Email-ul reprezentantului legal nu poate avea mai mult de 50 de caractere.", - "invalid": "Email-ul are un format invalid.", - "label": "Email*" + "required": "E-mail-ul reprezentantului legal este obligatoriu.", + "maxim": "E-mail-ul reprezentantului legal nu poate avea mai mult de 50 de caractere.", + "invalid": "E-mail-ul are un format invalid.", + "label": "E-mail*" }, "phone": { "required": "Numărul de telefon al reprezentantului legal este obligatoriu.", @@ -557,10 +557,10 @@ "label": "Nume și prenume*" }, "email": { - "required": "Email-ul membrului Consiliului Director este obligatoriu.", - "maxim": "Email-ul membrului Consiliului Director nu poate avea mai mult de 50 de caractere.", - "invalid": "Email-ul membrului Consiliului Director are un format invalid.", - "label": "Email*" + "required": "E-mail-ul membrului Consiliului Director este obligatoriu.", + "maxim": "E-mail-ul membrului Consiliului Director nu poate avea mai mult de 50 de caractere.", + "invalid": "E-mail-ul membrului Consiliului Director are un format invalid.", + "label": "E-mail*" }, "phone": { "required": "Telefonul directorului este invalid.", @@ -838,7 +838,7 @@ }, "list_header": { "name": "Nume", - "email": "Email", + "email": "E-mail", "phone": "Telefon", "status": "Acces general", "created": "Data adăugării" @@ -862,10 +862,10 @@ "label": "Nume și prenume*" }, "email": { - "required": "Email-ul este obligatoriu", - "max": "Email-ul poate avea maxim 50 de caractere", - "invalid": "Email-ul are un format invalid", - "label": "Email*" + "required": "E-mail-ul este obligatoriu", + "max": "E-mail-ul poate avea maxim 50 de caractere", + "invalid": "E-mail-ul are un format invalid", + "label": "E-mail*" }, "phone": { "required": "Numărul de telefon este obligatoriu", @@ -1084,7 +1084,7 @@ "define_active": "Faptul că aplicația este activă în contul organizației tale înseamnă că ai acces la ea și poți să o folosești.", "open": "Deschide aplicația", "pending": "Solicitarea ta așteaptă aprobare.", - "configure": "Aplicația aceasta trebuie instalată și configurata conform cu nevoile ONG-ului tău. Un membru al echipei Code for Romania te va contacta pentru detalii suplimentare în cel mai scurt timp, pe emailul persoanei de contact menționat în profilul tău de organizație. Îți mulțumim.", + "configure": "Aplicația aceasta trebuie instalată și configurata conform cu nevoile ONG-ului tău. Un membru al echipei Code for Romania te va contacta pentru detalii suplimentare în cel mai scurt timp, pe e-mailul persoanei de contact menționat în profilul tău de organizație. Îți mulțumim.", "cancel": "Anulează solicitare", "restore": "Contactează-ne pentru restituirea accesului.", "close_button": "Elimină aplicația", @@ -1178,7 +1178,7 @@ "header": { "org_name": "Organizație", "name": "Nume", - "email": "Email", + "email": "E-mail", "phone": "Telefon", "status": "Status", "created_on": "Data adăugării", @@ -1363,9 +1363,9 @@ "label": "Telefon*" }, "email": { - "required": "Email-ul este obligatoriu", - "max": "Email-ul nu poate avea mai mult de 50 de caractere", - "pattern": "Email-ul are un format invalid", + "required": "E-mail-ul este obligatoriu", + "max": "E-mail-ul nu poate avea mai mult de 50 de caractere", + "pattern": "E-mail-ul are un format invalid", "helper": "Adresa de e-mail la care solicitantul poate solicita serviciul", "label": "E-mail*" }, From 58561db7c23e6a68c9788aa19fbb465b49f6e0fb Mon Sep 17 00:00:00 2001 From: Tudor Amariei Date: Mon, 8 Apr 2024 09:42:20 +0300 Subject: [PATCH 3/4] Add gitignore for Mac & IDEA files --- .gitignore | Bin 0 -> 416 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..adad4b92e3c3d36a6cd252067189608e6d679169 GIT binary patch literal 416 zcmYL_!D<6B3`BGGR|t9w)TEz~vZMq`Te=~qLU4AKu83_JS-T;BUu{U+lkFK<^B7M( z2DkK-qH_=Mf*B=5=bQG>DhoQlE+t~a<1yOfwSAvZ#6Hc_+m17&u_|Eh;X*oqUKqZ_ z&CX&m&+LXV9dn>qoj)vRWkV4w=nxbVeGdwu6bu5CO+*l81wKK5iQ||owBgRqte-eh zCC>G6|Fl{;f2uf{Tzlu+!W!pgcWZ~Kumrho6_X|JB-8=zvcK(|@jP|egpQLpfQVix zVG7+q8GX;0wFp+*KQlKZ*jXQB1l}-1BdRSkKDE ay`gm^XSgB3hGUQ7{&?XI97<31?A#9~oQ;40 literal 0 HcmV?d00001 From 9eac44fbd56afacea0dc9bf78a889fd3eb52b3ab Mon Sep 17 00:00:00 2001 From: Birloi Florian Date: Fri, 24 May 2024 12:29:45 +0300 Subject: [PATCH 4/4] feat: update domains for civic center and practice for good and add beneficiaries --- .../1716531409199-Practice4GoodCCDomains.ts | 172 ++++++++++++++++++ ...716541753299-UpdatePracticesAndServices.ts | 39 ++++ .../civic-center-service-search-filter.dto.ts | 2 +- .../entities/civic-center-service.entity.ts | 3 +- .../entities/service-domain.entity.ts | 20 ++ .../entities/practice-program.entity.ts | 3 +- .../entities/practice_domain.entity.ts | 20 ++ .../enums/age-category.enum.ts | 22 ++- .../controllers/nomenclatures.controller.ts | 10 + .../shared/services/nomenclatures.service.ts | 14 ++ backend/src/shared/shared.module.ts | 4 + .../src/assets/locales/en/translation.json | 27 ++- .../src/assets/locales/ro/translation.json | 25 ++- .../src/common/enums/age-category.enum.ts | 24 ++- .../src/common/helpers/pulling-apps-helper.ts | 13 +- .../interfaces/pullin-app-domain.interface.ts | 5 + .../chip-selection/ChipSelection.tsx | 2 +- .../components/CivicCenterForm.tsx | 9 +- .../constants/age-categories.constants.ts | 31 +--- .../components/PracticeProgramForm.tsx | 8 +- .../civic-center-service-payload.interface.ts | 4 +- .../civic-center-service.interface.ts | 4 +- .../nomenclature/Nomenclature.queries.ts | 16 ++ .../nomenclature/Nomenclatures.service.ts | 13 +- 24 files changed, 419 insertions(+), 71 deletions(-) create mode 100644 backend/src/migrations/1716531409199-Practice4GoodCCDomains.ts create mode 100644 backend/src/migrations/1716541753299-UpdatePracticesAndServices.ts create mode 100644 backend/src/modules/civic-center-service/entities/service-domain.entity.ts create mode 100644 backend/src/modules/practice-program/entities/practice_domain.entity.ts create mode 100644 frontend/src/common/interfaces/pullin-app-domain.interface.ts diff --git a/backend/src/migrations/1716531409199-Practice4GoodCCDomains.ts b/backend/src/migrations/1716531409199-Practice4GoodCCDomains.ts new file mode 100644 index 00000000..fbf64c1f --- /dev/null +++ b/backend/src/migrations/1716531409199-Practice4GoodCCDomains.ts @@ -0,0 +1,172 @@ +import { MigrationInterface, QueryRunner, Table } from 'typeorm'; + +export class Practice4GoodCCDomains1716531409199 implements MigrationInterface { + name = 'Practice4GoodCCDomains1716531409199'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: '_domains_practice_programs', + columns: [ + { + name: 'id', + type: 'int', + isPrimary: true, + isGenerated: true, + generationStrategy: 'increment', + }, + { + name: 'name', + type: 'varchar', + }, + { + name: 'group', + type: 'varchar', + isNullable: true, + }, + ], + }), + true, + ); + + await queryRunner.createTable( + new Table({ + name: '_domains_civic_services', + columns: [ + { + name: 'id', + type: 'int', + isPrimary: true, + isGenerated: true, + generationStrategy: 'increment', + }, + { + name: 'name', + type: 'varchar', + }, + { + name: 'group', + type: 'varchar', + isNullable: true, + }, + ], + }), + true, + ); + + await queryRunner.query(` + INSERT INTO _domains_practice_programs (name, "group") VALUES + ('Advocacy', 'Advocacy'), + ('Artă & Cultură', 'Artă & Cultură'), + ('Tehnologie Civică', 'Tehnologie Civică'), + ('Societatea Civilă - Participare Civică', 'Societatea Civilă'), + ('Societatea Civilă - Comunitate', 'Societatea Civilă'), + ('Societatea Civilă - Voluntariat', 'Societatea Civilă'), + ('Dezvoltarea sectorului ONG', 'Dezvoltarea sectorului ONG'), + ('Democrație', 'Democrație'), + ('Democrație - Media', 'Democrație'), + ('Democrație - Transparență', 'Democrație'), + ('Intervenții În Caz De Dezastru', 'Intervenții în caz de dezastru'), + ('Creștere Economică - Dezvoltare rurală', 'Creștere Economică'), + ('Creștere Economică - Antreprenoriat social', 'Creștere Economică'), + ('Creștere Economică - Dezvoltare urbană', 'Creștere Economică'), + ('Educație', 'Educație'), + ('Educație Digitală', 'Educație'), + ('Educație - Învățare Continuă', 'Educație'), + ('Educație Pentru Copiii cu CES', 'Educație'), + ('Educație Incluzivă', 'Educație'), + ('Mediu', 'Mediu'), + ('Mediu - Animale și Faună sălbatică', 'Mediu'), + ('Mediu - Combaterea Schimbărilor Climatice', 'Mediu'), + ('Mediu - Agricultură Sustenabilă', 'Mediu'), + ('Sănătate', 'Sănătate'), + ('Sănătate - Intervenție de Urgență', 'Sănătate'), + ('Sănătate - HIV/AIDS', 'Sănătate'), + ('Sănătate Mentală', 'Sănătate'), + ('Sănătate Fizică', 'Sănătate'), + ('Sănătate Reproductivă', 'Sănătate'), + ('Drepturile Omului', 'Drepturile Omului'), + ('Drepturile Omului - Anti-Discriminare', 'Drepturile Omului'), + ('Drepturile Omului - Copii', 'Drepturile Omului'), + ('Drepturile Omului - Dizabilități', 'Drepturile Omului'), + ('Drepturile Omului - Violență Domestică', 'Drepturile Omului'), + ('Drepturile Omului - Egalitate de Gen', 'Drepturile Omului'), + ('Drepturile Omului - LGBTQ+', 'Drepturile Omului'), + ('Drepturile Omului - Minorități', 'Drepturile Omului'), + ('Drepturile Omului - Refugiați', 'Drepturile Omului'), + ('Drepturile Omului - Femei', 'Drepturile Omului'), + ('Ajutor Umanitar', 'Ajutor umanitar'), + ('Cooperare Internațională', 'Cooperare internațională'), + ('Asistență Juridică', 'Asistență juridică'), + ('Migrație', 'Asistență juridică'), + ('Altceva/General', 'Altceva/General'), + ('Filantropie', 'Filantropie'), + ('Combaterea Sărăciei - Apă Curată', 'Combaterea sărăciei'), + ('Combaterea Sărăciei - Securitate Alimentară', 'Combaterea sărăciei'), + ('Combaterea Sărăciei - Locuințe Sigure', 'Combaterea sărăciei'), + ('Cercetare', 'Cercetare'), + ('Servicii Sociale', 'Servicii Sociale'), + ('Sport', 'Sport'); + `); + + await queryRunner.query(` + INSERT INTO _domains_civic_services (name, "group") VALUES + ('Advocacy', 'Advocacy'), + ('Artă & Cultură', 'Artă & Cultură'), + ('Tehnologie Civică', 'Tehnologie Civică'), + ('Societatea Civilă - Participare Civică', 'Societatea Civilă'), + ('Societatea Civilă - Comunitate', 'Societatea Civilă'), + ('Societatea Civilă - Voluntariat', 'Societatea Civilă'), + ('Dezvoltarea sectorului ONG', 'Dezvoltarea sectorului ONG'), + ('Democrație', 'Democrație'), + ('Democrație - Media', 'Democrație'), + ('Democrație - Transparență', 'Democrație'), + ('Intervenții În Caz De Dezastru', 'Intervenții în caz de dezastru'), + ('Creștere Economică - Dezvoltare rurală', 'Creștere Economică'), + ('Creștere Economică - Antreprenoriat social', 'Creștere Economică'), + ('Creștere Economică - Dezvoltare urbană', 'Creștere Economică'), + ('Educație', 'Educație'), + ('Educație Digitală', 'Educație'), + ('Educație - Învățare Continuă', 'Educație'), + ('Educație Pentru Copiii cu CES', 'Educație'), + ('Educație Incluzivă', 'Educație'), + ('Mediu', 'Mediu'), + ('Mediu - Animale și Faună sălbatică', 'Mediu'), + ('Mediu - Combaterea Schimbărilor Climatice', 'Mediu'), + ('Mediu - Agricultură Sustenabilă', 'Mediu'), + ('Sănătate', 'Sănătate'), + ('Sănătate - Intervenție de Urgență', 'Sănătate'), + ('Sănătate - HIV/AIDS', 'Sănătate'), + ('Sănătate Mentală', 'Sănătate'), + ('Sănătate Fizică', 'Sănătate'), + ('Sănătate Reproductivă', 'Sănătate'), + ('Drepturile Omului', 'Drepturile Omului'), + ('Drepturile Omului - Anti-Discriminare', 'Drepturile Omului'), + ('Drepturile Omului - Copii', 'Drepturile Omului'), + ('Drepturile Omului - Dizabilități', 'Drepturile Omului'), + ('Drepturile Omului - Violență Domestică', 'Drepturile Omului'), + ('Drepturile Omului - Egalitate de Gen', 'Drepturile Omului'), + ('Drepturile Omului - LGBTQ+', 'Drepturile Omului'), + ('Drepturile Omului - Minorități', 'Drepturile Omului'), + ('Drepturile Omului - Refugiați', 'Drepturile Omului'), + ('Drepturile Omului - Femei', 'Drepturile Omului'), + ('Ajutor Umanitar', 'Ajutor umanitar'), + ('Cooperare Internațională', 'Cooperare internațională'), + ('Asistență Juridică', 'Asistență juridică'), + ('Migrație', 'Asistență juridică'), + ('Altceva/General', 'Altceva/General'), + ('Filantropie', 'Filantropie'), + ('Combaterea Sărăciei - Apă Curată', 'Combaterea sărăciei'), + ('Combaterea Sărăciei - Securitate Alimentară', 'Combaterea sărăciei'), + ('Combaterea Sărăciei - Locuințe Sigure', 'Combaterea sărăciei'), + ('Cercetare', 'Cercetare'), + ('Servicii Sociale', 'Servicii Sociale'), + ('Sport', 'Sport'); +`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('_domains_practice_programs'); + await queryRunner.dropTable('_domains_civic_services'); + } +} diff --git a/backend/src/migrations/1716541753299-UpdatePracticesAndServices.ts b/backend/src/migrations/1716541753299-UpdatePracticesAndServices.ts new file mode 100644 index 00000000..6f2dd8c7 --- /dev/null +++ b/backend/src/migrations/1716541753299-UpdatePracticesAndServices.ts @@ -0,0 +1,39 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class UpdatePracticesAndServices1716541753299 + implements MigrationInterface +{ + name = 'UpdatePracticesAndServices1716541753299'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."civic_center_service_age_categories_enum" RENAME TO "civic_center_service_age_categories_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "public"."civic_center_service_age_categories_enum" AS ENUM('COPII', 'TINERI', 'ADULTI', 'VARSTNICI', 'FAMILIE', 'RISC_DE_SARACIE', 'ADICTII', 'AFECTIUNI_MEDICALE', 'AFECTIUNI_PSIHICE', 'DIZABILITATI', 'COMUNITATI_IZOLATE', 'FARA_ADAPOST', 'PRIVATE_DE_LIBERTATE', 'TRAFICULUI_DE_PERSOANE', 'VIOLENTEI_DOMESTICE', 'SOMERI', 'APARTINATORII_BENEFICIARILOR')`, + ); + await queryRunner.query( + `ALTER TABLE "civic_center_service" ALTER COLUMN "age_categories" TYPE "public"."civic_center_service_age_categories_enum"[] USING "age_categories"::"text"::"public"."civic_center_service_age_categories_enum"[]`, + ); + await queryRunner.query( + `DROP TYPE "public"."civic_center_service_age_categories_enum_old"`, + ); + await queryRunner.query(`DELETE FROM "civic_center_service_to_domain"`); + await queryRunner.query(`DELETE FROM "practice_program_to_domain"`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."civic_center_service_age_categories_enum_old" AS ENUM('0-18', '18-25', '25-35', '35-60', '60+')`, + ); + await queryRunner.query( + `ALTER TABLE "civic_center_service" ALTER COLUMN "age_categories" TYPE "public"."civic_center_service_age_categories_enum_old"[] USING "age_categories"::"text"::"public"."civic_center_service_age_categories_enum_old"[]`, + ); + await queryRunner.query( + `DROP TYPE "public"."civic_center_service_age_categories_enum"`, + ); + await queryRunner.query( + `ALTER TYPE "public"."civic_center_service_age_categories_enum_old" RENAME TO "civic_center_service_age_categories_enum"`, + ); + } +} diff --git a/backend/src/modules/civic-center-service/dto/civic-center-service-search-filter.dto.ts b/backend/src/modules/civic-center-service/dto/civic-center-service-search-filter.dto.ts index 73ded0fe..6d76d145 100644 --- a/backend/src/modules/civic-center-service/dto/civic-center-service-search-filter.dto.ts +++ b/backend/src/modules/civic-center-service/dto/civic-center-service-search-filter.dto.ts @@ -21,5 +21,5 @@ export class CivicCenterServiceSearchFilterDto extends OmitType(BaseFilterDto, [ @IsArray() @IsOptional() - ageCategories?: AgeCategory[]; + ageCategories?: AgeCategory[]; //TODO: this needs to be renamed to beneficiaries } diff --git a/backend/src/modules/civic-center-service/entities/civic-center-service.entity.ts b/backend/src/modules/civic-center-service/entities/civic-center-service.entity.ts index d31cec32..23f5377a 100644 --- a/backend/src/modules/civic-center-service/entities/civic-center-service.entity.ts +++ b/backend/src/modules/civic-center-service/entities/civic-center-service.entity.ts @@ -13,6 +13,7 @@ import { } from 'typeorm'; import { AgeCategory } from '../../practice-program/enums/age-category.enum'; import { Feedback } from './feedback.entity'; +import { ServiceDomain } from './service-domain.entity'; @Entity() export class CivicCenterService extends BaseEntity { @@ -67,7 +68,7 @@ export class CivicCenterService extends BaseEntity { }, inverseJoinColumn: { name: 'domain_id', referencedColumnName: 'id' }, }) - domains: Domain[]; + domains: ServiceDomain[]; @Column({ type: 'enum', diff --git a/backend/src/modules/civic-center-service/entities/service-domain.entity.ts b/backend/src/modules/civic-center-service/entities/service-domain.entity.ts new file mode 100644 index 00000000..73e09b01 --- /dev/null +++ b/backend/src/modules/civic-center-service/entities/service-domain.entity.ts @@ -0,0 +1,20 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity('_domains_civic_services') +export class ServiceDomain { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ + type: 'varchar', + name: 'name', + }) + name: string; + + @Column({ + type: 'varchar', + name: 'group', + nullable: true, + }) + group: string; +} diff --git a/backend/src/modules/practice-program/entities/practice-program.entity.ts b/backend/src/modules/practice-program/entities/practice-program.entity.ts index f1bc14d5..fd34eebf 100644 --- a/backend/src/modules/practice-program/entities/practice-program.entity.ts +++ b/backend/src/modules/practice-program/entities/practice-program.entity.ts @@ -11,6 +11,7 @@ import { ManyToMany, ManyToOne, } from 'typeorm'; +import { PracticeDomain } from './practice_domain.entity'; @Entity() export class PracticeProgram extends BaseEntity { @@ -82,7 +83,7 @@ export class PracticeProgram extends BaseEntity { }, inverseJoinColumn: { name: 'domain_id', referencedColumnName: 'id' }, }) - domains: Domain[]; + domains: PracticeDomain[]; @ManyToMany(() => Faculty, { cascade: true, onDelete: 'CASCADE' }) @JoinTable({ diff --git a/backend/src/modules/practice-program/entities/practice_domain.entity.ts b/backend/src/modules/practice-program/entities/practice_domain.entity.ts new file mode 100644 index 00000000..c7594313 --- /dev/null +++ b/backend/src/modules/practice-program/entities/practice_domain.entity.ts @@ -0,0 +1,20 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity('_domains_practice_programs') +export class PracticeDomain { + @PrimaryGeneratedColumn('increment') + id: number; + + @Column({ + type: 'varchar', + name: 'name', + }) + name: string; + + @Column({ + type: 'varchar', + name: 'group', + nullable: true, + }) + group: string; +} diff --git a/backend/src/modules/practice-program/enums/age-category.enum.ts b/backend/src/modules/practice-program/enums/age-category.enum.ts index 2064d15e..23634939 100644 --- a/backend/src/modules/practice-program/enums/age-category.enum.ts +++ b/backend/src/modules/practice-program/enums/age-category.enum.ts @@ -1,7 +1,19 @@ export enum AgeCategory { - '0_18' = '0-18', - '18_25' = '18-25', - '25_35' = '25-35', - '35_60' = '35-60', - 'OVER_60' = '60+', + COPII = 'COPII', + TINERI = 'TINERI', + ADULTI = 'ADULTI', + VARSTNICI = 'VARSTNICI', + FAMILIE = 'FAMILIE', + RISC_DE_SARACIE = 'RISC_DE_SARACIE', + ADICTII = 'ADICTII', + AFECTIUNI_MEDICALE = 'AFECTIUNI_MEDICALE', + AFECTIUNI_PSIHICE = 'AFECTIUNI_PSIHICE', + DIZABILITATI = 'DIZABILITATI', + COMUNITATI_IZOLATE = 'COMUNITATI_IZOLATE', + FARA_ADAPOST = 'FARA_ADAPOST', + PRIVATE_DE_LIBERTATE = 'PRIVATE_DE_LIBERTATE', + TRAFICULUI_DE_PERSOANE = 'TRAFICULUI_DE_PERSOANE', + VIOLENTEI_DOMESTICE = 'VIOLENTEI_DOMESTICE', + SOMERI = 'SOMERI', + APARTINATORII_BENEFICIARILOR = 'APARTINATORII_BENEFICIARILOR', } diff --git a/backend/src/shared/controllers/nomenclatures.controller.ts b/backend/src/shared/controllers/nomenclatures.controller.ts index 28bc22ed..9a6b806e 100644 --- a/backend/src/shared/controllers/nomenclatures.controller.ts +++ b/backend/src/shared/controllers/nomenclatures.controller.ts @@ -58,4 +58,14 @@ export class NomenclaturesController { getSkills() { return this.nomenclaturesService.getSkills({}); } + + @Get('practice-domains') + getPracticeDomains() { + return this.nomenclaturesService.getPracticeDomains({}); + } + + @Get('service-domains') + getServiceDomains() { + return this.nomenclaturesService.getServiceDomains({}); + } } diff --git a/backend/src/shared/services/nomenclatures.service.ts b/backend/src/shared/services/nomenclatures.service.ts index 5ea5ad18..04be1dfc 100644 --- a/backend/src/shared/services/nomenclatures.service.ts +++ b/backend/src/shared/services/nomenclatures.service.ts @@ -13,6 +13,8 @@ import { CitySearchDto } from '../dto/city-search.dto'; import { NOMENCLATURE_ERRORS } from '../constants/nomenclature-error.constants'; import { Coalition } from '../entities/coalition.entity'; import { Federation } from '../entities/federation.entity'; +import { PracticeDomain } from 'src/modules/practice-program/entities/practice_domain.entity'; +import { ServiceDomain } from 'src/modules/civic-center-service/entities/service-domain.entity'; @Injectable() export class NomenclaturesService { @@ -33,6 +35,10 @@ export class NomenclaturesService { private readonly facultiesRepository: Repository, @InjectRepository(Skill) private readonly skillsRepository: Repository, + @InjectRepository(PracticeDomain) + private readonly practiceDomainRepository: Repository, + @InjectRepository(ServiceDomain) + private readonly serviceDomainRepository: Repository, ) {} public getCity(conditions: FindOneOptions) { @@ -141,4 +147,12 @@ export class NomenclaturesService { public createSkills(skills: Partial[]): Promise { return this.skillsRepository.save(skills); } + + public getPracticeDomains(conditions: FindManyOptions) { + return this.practiceDomainRepository.find(conditions); + } + + public getServiceDomains(conditions: FindManyOptions) { + return this.serviceDomainRepository.find(conditions); + } } diff --git a/backend/src/shared/shared.module.ts b/backend/src/shared/shared.module.ts index 21e709ca..976e829b 100644 --- a/backend/src/shared/shared.module.ts +++ b/backend/src/shared/shared.module.ts @@ -16,6 +16,8 @@ import { AnafService, NomenclaturesService } from './services'; import { HttpModule } from '@nestjs/axios'; import { S3FileManagerService } from './services/s3-file-manager.service'; import { FileManagerService } from './services/file-manager.service'; +import { PracticeDomain } from 'src/modules/practice-program/entities/practice_domain.entity'; +import { ServiceDomain } from 'src/modules/civic-center-service/entities/service-domain.entity'; @Global() @Module({ @@ -29,6 +31,8 @@ import { FileManagerService } from './services/file-manager.service'; Coalition, Faculty, Skill, + PracticeDomain, + ServiceDomain, ]), HttpModule, ], diff --git a/frontend/src/assets/locales/en/translation.json b/frontend/src/assets/locales/en/translation.json index fc127175..4188b17c 100644 --- a/frontend/src/assets/locales/en/translation.json +++ b/frontend/src/assets/locales/en/translation.json @@ -1243,6 +1243,25 @@ "description": "TODO#17: Lorem ipsum", "add_button": "Add Service" }, + "beneficiaries": { + "COPII": "copii (0-14 ani)", + "TINERI": "tineri (15-18 ani)", + "ADULTI": "adulți (18-25 ani)", + "VARSTNICI": "vârstnici (>65 ani)", + "FAMILIE": "familie", + "RISC_DE_SARACIE": "persoane aflate în risc de sărăcie", + "ADICTII": "persoane cu adicţii (alcool, droguri, jocuri de noroc etc.)", + "AFECTIUNI_MEDICALE": "persoane cu afecţiuni medicale", + "AFECTIUNI_PSIHICE": "persoane cu afecţiuni psihice", + "DIZABILITATI": "persoane cu dizabilităţi", + "COMUNITATI_IZOLATE": "persoane din comunităţi izolate", + "FARA_ADAPOST": "persoane fără adăpost", + "PRIVATE_DE_LIBERTATE": "persoane private de libertate", + "TRAFICULUI_DE_PERSOANE": "victime ale traficului de persoane", + "VIOLENTEI_DOMESTICE": "victime ale violenţei domestice", + "SOMERI": "şomeri de lungă durată", + "APARTINATORII_BENEFICIARILOR": "servicii sociale de suport pentru aparţinătorii beneficiarilor" + }, "list": { "error": "Error loading the list of services" }, @@ -1324,9 +1343,9 @@ "helper": "Select at least one domain" }, "age_category": { - "label": "Age category*", - "helper": "Select a minimum of one or all age categories", - "required": "Age category is mandatory" + "label": "Beneficiary*", + "helper": "Select a minimum of one or all beneficiaries", + "required": "Beneficiary is mandatory" }, "online": { "toggle": { @@ -1404,7 +1423,7 @@ }, "details": { "available": "Available", - "age_category": "Age category", + "age_category": "Beneficiary", "domains": "Domains", "email": "E-mail", "phone": "Phone", diff --git a/frontend/src/assets/locales/ro/translation.json b/frontend/src/assets/locales/ro/translation.json index 4839ed0d..fa6248a4 100644 --- a/frontend/src/assets/locales/ro/translation.json +++ b/frontend/src/assets/locales/ro/translation.json @@ -1247,6 +1247,25 @@ "description": "Aici poți vizualiza și edita toate serviciile oferite de organizația ta.", "add_button": "Adaugă Serviciu" }, + "beneficiaries": { + "COPII": "copii (0-14 ani)", + "TINERI": "tineri (15-18 ani)", + "ADULTI": "adulți (18-25 ani)", + "VARSTNICI": "vârstnici (>65 ani)", + "FAMILIE": "familie", + "RISC_DE_SARACIE": "persoane aflate în risc de sărăcie", + "ADICTII": "persoane cu adicţii (alcool, droguri, jocuri de noroc etc.)", + "AFECTIUNI_MEDICALE": "persoane cu afecţiuni medicale", + "AFECTIUNI_PSIHICE": "persoane cu afecţiuni psihice", + "DIZABILITATI": "persoane cu dizabilităţi", + "COMUNITATI_IZOLATE": "persoane din comunităţi izolate", + "FARA_ADAPOST": "persoane fără adăpost", + "PRIVATE_DE_LIBERTATE": "persoane private de libertate", + "TRAFICULUI_DE_PERSOANE": "victime ale traficului de persoane", + "VIOLENTEI_DOMESTICE": "victime ale violenţei domestice", + "SOMERI": "şomeri de lungă durată", + "APARTINATORII_BENEFICIARILOR": "servicii sociale de suport pentru aparţinătorii beneficiarilor" + }, "list": { "error": "Eroare la încărcarea listei de servicii" }, @@ -1328,8 +1347,8 @@ "helper": "Selectează minim un domeniu" }, "age_category": { - "label": "Categorie vârstă*", - "helper": "Selectează minim o categorie de vârstă, sau pe toate", + "label": "Beneficiari*", + "helper": "Selectează minim un beneficiar, sau pe toate", "required": "Categoria de vârstă este obligatorie" }, "online": { @@ -1408,7 +1427,7 @@ }, "details": { "available": "Disponibil", - "age_category": "Categorie de vârstă", + "age_category": "Beneficiar", "domains": "Domenii", "email": "E-mail", "phone": "Telefon", diff --git a/frontend/src/common/enums/age-category.enum.ts b/frontend/src/common/enums/age-category.enum.ts index 2064d15e..c9742666 100644 --- a/frontend/src/common/enums/age-category.enum.ts +++ b/frontend/src/common/enums/age-category.enum.ts @@ -1,7 +1,19 @@ -export enum AgeCategory { - '0_18' = '0-18', - '18_25' = '18-25', - '25_35' = '25-35', - '35_60' = '35-60', - 'OVER_60' = '60+', +export enum Beneficiary { + COPII = 'COPII', + TINERI = 'TINERI', + ADULTI = 'ADULTI', + VARSTNICI = 'VARSTNICI', + FAMILIE = 'FAMILIE', + RISC_DE_SARACIE = 'RISC_DE_SARACIE', + ADICTII = 'ADICTII', + AFECTIUNI_MEDICALE = 'AFECTIUNI_MEDICALE', + AFECTIUNI_PSIHICE = 'AFECTIUNI_PSIHICE', + DIZABILITATI = 'DIZABILITATI', + COMUNITATI_IZOLATE = 'COMUNITATI_IZOLATE', + FARA_ADAPOST = 'FARA_ADAPOST', + PRIVATE_DE_LIBERTATE = 'PRIVATE_DE_LIBERTATE', + TRAFICULUI_DE_PERSOANE = 'TRAFICULUI_DE_PERSOANE', + VIOLENTEI_DOMESTICE = 'VIOLENTEI_DOMESTICE', + SOMERI = 'SOMERI', + APARTINATORII_BENEFICIARILOR = 'APARTINATORII_BENEFICIARILOR', } diff --git a/frontend/src/common/helpers/pulling-apps-helper.ts b/frontend/src/common/helpers/pulling-apps-helper.ts index 0d781b8c..8a58c427 100644 --- a/frontend/src/common/helpers/pulling-apps-helper.ts +++ b/frontend/src/common/helpers/pulling-apps-helper.ts @@ -1,7 +1,6 @@ import { CivicCenterService } from '../../services/civic-center-service/interfaces/civic-center-service.interface'; import { PracticeProgram } from '../../services/practice-program/interfaces/practice-program.interface'; import i18n from '../config/i18n'; -import { AgeCategory } from '../enums/age-category.enum'; import { formatDateMonthYear } from './format.helper'; const translations = { @@ -9,14 +8,6 @@ const translations = { unlimited: i18n.t('practice_program:details.deadline_unlimited'), }; -const AgeCategoriesMapper = { - [AgeCategory['0_18']]: '0-18', - [AgeCategory['18_25']]: '18-25', - [AgeCategory['25_35']]: '25-35', - [AgeCategory['35_60']]: '35-60', - [AgeCategory.OVER_60]: '>60', -}; - export const calculatePeriod = (item: PracticeProgram | CivicCenterService) => { if (!item?.endDate) { const startDate = formatDateMonthYear(item?.startDate); @@ -33,5 +24,7 @@ export const dataToCsv = (items: { id: number; name: string }[]): string => { }; export const formatAgeCategories = (item: CivicCenterService) => { - return item?.ageCategories.map((ageCategory) => AgeCategoriesMapper[ageCategory]).join(', '); + return item?.ageCategories + .map((key) => i18n.t(`beneficiaries.${key}`, { ns: 'civic_center_service' })) + .join(', '); }; diff --git a/frontend/src/common/interfaces/pullin-app-domain.interface.ts b/frontend/src/common/interfaces/pullin-app-domain.interface.ts new file mode 100644 index 00000000..df1dc4b4 --- /dev/null +++ b/frontend/src/common/interfaces/pullin-app-domain.interface.ts @@ -0,0 +1,5 @@ +export interface PullingAppDomain { + id: number; + name: string; + group?: string; +} diff --git a/frontend/src/components/chip-selection/ChipSelection.tsx b/frontend/src/components/chip-selection/ChipSelection.tsx index 443cf6e7..3396235e 100644 --- a/frontend/src/components/chip-selection/ChipSelection.tsx +++ b/frontend/src/components/chip-selection/ChipSelection.tsx @@ -45,7 +45,7 @@ const ChipSelection = ({ helperText, defaultItems = [], onItemsChange, - values, + values = [], error, readonly, id, diff --git a/frontend/src/pages/civic-center-service/components/CivicCenterForm.tsx b/frontend/src/pages/civic-center-service/components/CivicCenterForm.tsx index fa687415..d43969aa 100644 --- a/frontend/src/pages/civic-center-service/components/CivicCenterForm.tsx +++ b/frontend/src/pages/civic-center-service/components/CivicCenterForm.tsx @@ -18,9 +18,8 @@ import ServerSelect from '../../../components/server-select/ServerSelect'; import Textarea from '../../../components/Textarea/Textarea'; import Toggle from '../../../components/toggle/Toggle'; import { CivicCenterServicePayload } from '../../../services/civic-center-service/interfaces/civic-center-service-payload.interface'; -import { useDomainsQuery } from '../../../services/nomenclature/Nomenclature.queries'; +import { useServiceDomainsQuery } from '../../../services/nomenclature/Nomenclature.queries'; import { getCities } from '../../../services/nomenclature/Nomenclatures.service'; -import { useNomenclature } from '../../../store/nomenclature/nomenclature.selectors'; import { CivicCenterFormConfig } from '../config/CivicCenterFormConfig'; import { ageCategories } from '../constants/age-categories.constants'; import SubsectionHeader from './SubsectionHeader'; @@ -40,14 +39,12 @@ const CivicCenterForm = ({ onChangeFormValidity, resetField, }: CivicCenterFormProps) => { - const { domains } = useNomenclature(); - // component state const [civicCenterProgramPeriodError, setCivicCenterPeriodError] = useState(); const [civicCenterMandatoryAccessError, setCivicCenterMandatoryAccessError] = useState(); // load nomenclature data - useDomainsQuery(); + const { data: domains } = useServiceDomainsQuery(); // translarions const { t } = useTranslation(['civic_center_service']); @@ -268,7 +265,7 @@ const CivicCenterForm = ({ )[ CivicCenterFormConfig.domains.key diff --git a/frontend/src/pages/civic-center-service/constants/age-categories.constants.ts b/frontend/src/pages/civic-center-service/constants/age-categories.constants.ts index c4a9af75..577b3516 100644 --- a/frontend/src/pages/civic-center-service/constants/age-categories.constants.ts +++ b/frontend/src/pages/civic-center-service/constants/age-categories.constants.ts @@ -1,24 +1,9 @@ -import { AgeCategory } from '../../../common/enums/age-category.enum'; +import i18n from '../../../common/config/i18n'; +import { Beneficiary } from '../../../common/enums/age-category.enum'; -export const ageCategories = [ - { - name: '0 - 18', - id: AgeCategory['0_18'], - }, - { - name: '18 - 25', - id: AgeCategory['18_25'], - }, - { - name: '25 - 35', - id: AgeCategory['25_35'], - }, - { - name: '35 - 60', - id: AgeCategory['35_60'], - }, - { - name: '> 60', - id: AgeCategory.OVER_60, - }, -]; +export const ageCategories = Object.keys(Beneficiary).map((key) => { + return { + name: i18n.t(`beneficiaries.${key}`, { ns: 'civic_center_service' }), + id: key, + }; +}); diff --git a/frontend/src/pages/pactice-program/components/PracticeProgramForm.tsx b/frontend/src/pages/pactice-program/components/PracticeProgramForm.tsx index 64d5a3a5..c1a2a2e3 100644 --- a/frontend/src/pages/pactice-program/components/PracticeProgramForm.tsx +++ b/frontend/src/pages/pactice-program/components/PracticeProgramForm.tsx @@ -10,8 +10,8 @@ import Textarea from '../../../components/Textarea/Textarea'; import ChipSelection from '../../../components/chip-selection/ChipSelection'; import { useNomenclature } from '../../../store/selectors'; import { - useDomainsQuery, useFacultiesQuery, + usePracticeDomainsQuery, useSkillsQuery, } from '../../../services/nomenclature/Nomenclature.queries'; import CreatableSelectComponent from '../../../components/creatable-multi-select/CreatableMultiSelect'; @@ -34,7 +34,7 @@ const PracticeProgramForm = ({ onChangeFormValidity, }: PracticeProgramFormProps) => { // store data - const { domains, skills, faculties } = useNomenclature(); + const { skills, faculties } = useNomenclature(); // component state const [practiceProgramPeriodError, setPracticeProgramPeriodError] = useState(); @@ -44,7 +44,7 @@ const PracticeProgramForm = ({ const { t } = useTranslation(['practice_program']); // load nomenclature data - useDomainsQuery(); + const { data: domains } = usePracticeDomainsQuery(); useSkillsQuery(); useFacultiesQuery(); @@ -312,7 +312,7 @@ const PracticeProgramForm = ({ )[ PracticeProgramFormConfig.domains.key diff --git a/frontend/src/services/civic-center-service/interfaces/civic-center-service-payload.interface.ts b/frontend/src/services/civic-center-service/interfaces/civic-center-service-payload.interface.ts index 36253859..06151c97 100644 --- a/frontend/src/services/civic-center-service/interfaces/civic-center-service-payload.interface.ts +++ b/frontend/src/services/civic-center-service/interfaces/civic-center-service-payload.interface.ts @@ -1,4 +1,4 @@ -import { AgeCategory } from '../../../common/enums/age-category.enum'; +import { Beneficiary } from '../../../common/enums/age-category.enum'; import { ISelectData } from '../../../common/helpers/format.helper'; import { BaseEntity } from '../../../common/interfaces/base-entity.interface'; import { City } from '../../../common/interfaces/city.interface'; @@ -12,7 +12,7 @@ export interface CivicCenterServicePayload extends BaseEntity { shortDescription: string; longDescription: string; domains: number[]; - ageCategories: AgeCategory[]; + ageCategories: Beneficiary[]; isPeriodNotDetermined: boolean; hasOnlineAccess: boolean; onlineAccessLink?: string | null; diff --git a/frontend/src/services/civic-center-service/interfaces/civic-center-service.interface.ts b/frontend/src/services/civic-center-service/interfaces/civic-center-service.interface.ts index 008132b5..c0bb9865 100644 --- a/frontend/src/services/civic-center-service/interfaces/civic-center-service.interface.ts +++ b/frontend/src/services/civic-center-service/interfaces/civic-center-service.interface.ts @@ -1,4 +1,4 @@ -import { AgeCategory } from '../../../common/enums/age-category.enum'; +import { Beneficiary } from '../../../common/enums/age-category.enum'; import { BaseEntity } from '../../../common/interfaces/base-entity.interface'; import { City } from '../../../common/interfaces/city.interface'; import { Domain } from '../../../common/interfaces/domain.interface'; @@ -12,7 +12,7 @@ export interface CivicCenterService extends BaseEntity { shortDescription: string; longDescription: string; domains: Domain[]; - ageCategories: AgeCategory[]; + ageCategories: Beneficiary[]; hasOnlineAccess: boolean; onlineAccessLink?: string; onlineAccessDescription?: string; diff --git a/frontend/src/services/nomenclature/Nomenclature.queries.ts b/frontend/src/services/nomenclature/Nomenclature.queries.ts index 1476f9db..ac76b59a 100644 --- a/frontend/src/services/nomenclature/Nomenclature.queries.ts +++ b/frontend/src/services/nomenclature/Nomenclature.queries.ts @@ -13,6 +13,8 @@ import { getCoalitions, getSkills, getFaculties, + getPracticeDomains, + getServiceDomains, } from './Nomenclatures.service'; import { Coalition } from '../../common/interfaces/coalitions.interface'; import { Federation } from '../../common/interfaces/federations.interface'; @@ -48,6 +50,20 @@ export const useDomainsQuery = () => { }); }; +export const usePracticeDomainsQuery = () => { + return useQuery(['practice-domains'], () => getPracticeDomains(), { + cacheTime: 1000 * 60 * 60, + staleTime: 1000 * 60 * 60, + }); +}; + +export const useServiceDomainsQuery = () => { + return useQuery(['service-domains'], () => getServiceDomains(), { + cacheTime: 1000 * 60 * 60, + staleTime: 1000 * 60 * 60, + }); +}; + export const useRegionsQuery = () => { const { setRegions } = useStore(); return useQuery('regions', () => getRegions(), { diff --git a/frontend/src/services/nomenclature/Nomenclatures.service.ts b/frontend/src/services/nomenclature/Nomenclatures.service.ts index 776da13c..472c552e 100644 --- a/frontend/src/services/nomenclature/Nomenclatures.service.ts +++ b/frontend/src/services/nomenclature/Nomenclatures.service.ts @@ -1,9 +1,10 @@ -import { Domain } from 'domain'; import { City } from '../../common/interfaces/city.interface'; import { Coalition } from '../../common/interfaces/coalitions.interface'; import { County } from '../../common/interfaces/county.interface'; +import { Domain } from '../../common/interfaces/domain.interface'; import { Faculty } from '../../common/interfaces/faculty.interface'; import { Federation } from '../../common/interfaces/federations.interface'; +import { PullingAppDomain } from '../../common/interfaces/pullin-app-domain.interface'; import { Region } from '../../common/interfaces/region.interface'; import { Skill } from '../../common/interfaces/skill.interface'; import API from '../API'; @@ -24,10 +25,18 @@ export const getCities = (searchTerm: string, countyId?: number): Promise res.data); }; -export const getDomains = (): Promise => { +export const getDomains = (): Promise => { return API.get(`/nomenclatures/domains`).then((res) => res.data); }; +export const getPracticeDomains = (): Promise => { + return API.get(`/nomenclatures/practice-domains`).then((res) => res.data); +}; + +export const getServiceDomains = (): Promise => { + return API.get(`/nomenclatures/service-domains`).then((res) => res.data); +}; + export const getRegions = (): Promise => { return API.get(`/nomenclatures/regions`).then((res) => res.data); };