From 773f9648b27f187d5d9e149635153168eae162d4 Mon Sep 17 00:00:00 2001 From: Alaguraj0361 Date: Mon, 18 Aug 2025 19:11:03 +0530 Subject: [PATCH 1/3] home page blog section updated --- api/blogs.js | 4 ++ components/BlogSection/BlogSection.js | 96 ++++++++++++++++----------- next-i18next.config.js | 3 +- pages/blog/[slug].js | 70 +++++++++++++------ pages/index.js | 2 +- public/locales/en/blog.json | 22 ++++++ public/locales/es/blog.json | 22 ++++++ utils/constant.utils.js | 52 +++++++++++++++ 8 files changed, 209 insertions(+), 62 deletions(-) create mode 100644 public/locales/en/blog.json create mode 100644 public/locales/es/blog.json diff --git a/api/blogs.js b/api/blogs.js index f11ff44..068e8f5 100644 --- a/api/blogs.js +++ b/api/blogs.js @@ -180,3 +180,7 @@ This article provides general information only. Consult qualified immigration co ]; export default blogs; + + + + diff --git a/components/BlogSection/BlogSection.js b/components/BlogSection/BlogSection.js index 1286f68..9542dce 100644 --- a/components/BlogSection/BlogSection.js +++ b/components/BlogSection/BlogSection.js @@ -1,48 +1,64 @@ import React from "react"; -import blogs from '../../api/blogs' +import blogs from '../../api/blogs'; import Link from "next/link"; import SectionTitle from "../SectionTitle/SectionTitle"; import Image from "next/image"; +import { useTranslation } from 'next-i18next'; +import blog from "../../utils/constant.utils"; - -const ClickHandler = () => { - window.scrollTo(10, 0); -} +const ClickHandler = () => window.scrollTo(10, 0); const BlogSection = () => { - return ( -
-
- -
-
- {blogs.map((blog, bl) => ( -
-
-
- -
-
- {/* */} -

{blog.title}

-
-

- {blog.para} -

- Know More -
-
-
-
- ))} -
-
-
-
- ); -} + const { t } = useTranslation('blog'); -export default BlogSection; \ No newline at end of file + return ( +
+
+ +
+
+ {blog.map((blog) => { + const blogTexts = t(`posts.${blog.slug}`, { returnObjects: true }); + return ( +
+
+
+ {blogTexts.title} +
+
+

+ + {blogTexts.title} + +

+
+

{blogTexts.para}

+ + {t('knowMore')} + +
+
+
+
+ ); + })} +
+
+
+
+ ); +}; + +export default BlogSection; diff --git a/next-i18next.config.js b/next-i18next.config.js index 2eb1d60..84ca021 100644 --- a/next-i18next.config.js +++ b/next-i18next.config.js @@ -1,4 +1,3 @@ -const { default: OurApproach } = require("./pages/our-approach"); module.exports = { i18n: { @@ -19,5 +18,5 @@ module.exports = { // Vidhya - OurApproach -// Alagu Raj - 'common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction' +// Alagu Raj - 'common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction', 'blog' diff --git a/pages/blog/[slug].js b/pages/blog/[slug].js index e41e3b1..4a139bc 100644 --- a/pages/blog/[slug].js +++ b/pages/blog/[slug].js @@ -1,6 +1,9 @@ +// pages/blog/[slug].js import React, { Fragment } from 'react'; import { useRouter } from 'next/router'; -import blogs from '../../api/blogs'; +import { useTranslation } from 'next-i18next'; +import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; +import blogs from '../../api/blogs'; // Static metadata like images, author, etc. import Link from 'next/link'; import PageTitle from '../../components/pagetitle/PageTitle'; import Navbar2 from '../../components/Navbar2/Navbar2'; @@ -8,17 +11,25 @@ import Footer from '../../components/footer/Footer'; import Scrollbar from '../../components/scrollbar/scrollbar'; import Image from 'next/image'; -const BlogSingle = (props) => { +const BlogSingle = () => { const router = useRouter(); const { slug } = router.query; - const BlogDetails = blogs.find(blog => blog.slug === slug); + const { t } = useTranslation('blog'); - if (!BlogDetails) { + if (!slug) return null; // Avoid hydration mismatch on first load + + // Localized content from blog.json + const blogContent = t(`posts.${slug}`, { returnObjects: true }); + + // Static metadata (images, date, author) + const blogMeta = blogs.find(blog => blog.slug === slug); + + if (!blogMeta || !blogContent?.title) { return (

Blog not found!

- Back to Blog + ← Back to Blog
); } @@ -26,37 +37,34 @@ const BlogSingle = (props) => { return ( - +
-
+
-
+
-
+
{BlogDetails.title}
    -
  • {BlogDetails.create_at}
  • -
  • - By{' '} - {BlogDetails.authorTitle} -
  • +
  • {blogMeta.create_at}
  • +
  • By {blogMeta.authorTitle}
-

{BlogDetails.title}

-
+

{blogContent.title}

+
@@ -70,4 +78,28 @@ const BlogSingle = (props) => { ); }; +export async function getStaticPaths() { + const locales = ['en', 'es']; + + const paths = locales.flatMap(locale => + blogs.map(blog => ({ + params: { slug: blog.slug }, + locale, + })) + ); + + return { + paths, + fallback: false, + }; +} + +export async function getStaticProps({ locale }) { + return { + props: { + ...(await serverSideTranslations(locale, ['common', 'menu', 'blog'])), + }, + }; +} + export default BlogSingle; diff --git a/pages/index.js b/pages/index.js index de920eb..3431bb4 100644 --- a/pages/index.js +++ b/pages/index.js @@ -40,7 +40,7 @@ export default HomePage; export async function getStaticProps({ locale }) { return { props: { - ...(await serverSideTranslations(locale, ['common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction'])), // Add 'home', 'footer', etc. if needed + ...(await serverSideTranslations(locale, ['common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction', 'blog'])), // Add 'home', 'footer', etc. if needed }, }; } diff --git a/public/locales/en/blog.json b/public/locales/en/blog.json new file mode 100644 index 0000000..392b89f --- /dev/null +++ b/public/locales/en/blog.json @@ -0,0 +1,22 @@ +{ + "sectionSubTitle": "Our Blog", + "sectionTitle": "Latest News & Press", + "knowMore": "Know More", + "posts": { + "new-tps-designations-what-you-need-to-know": { + "title": "New TPS Designations: What You Need to Know", + "summary": "Recent policy changes affect thousands of immigrants. Learn how temporary protected status updates may impact your case and what actions to take.", + "description": "

Recent policy changes affect thousands of immigrants. Learn how temporary protected status updates...

... full content here ..." + }, + "h1b-season-2025-preparation-strategies": { + "title": "H-1B Season 2025: Preparation Strategies", + "summary": "The annual H-1B lottery approaches. Our comprehensive guide helps employers and workers navigate the process.", + "description": "

The H-1B registration period for the fiscal year 2026 closed recently...

... full content here ..." + }, + "family-immigration-backlogs-alternative-options": { + "title": "Family Immigration Backlogs: Alternative Options", + "summary": "While family preference categories face delays, discover alternative pathways to reunite with loved ones.", + "description": "

While family preference categories face delays...

... full content here ..." + } + } +} \ No newline at end of file diff --git a/public/locales/es/blog.json b/public/locales/es/blog.json new file mode 100644 index 0000000..aad4cd9 --- /dev/null +++ b/public/locales/es/blog.json @@ -0,0 +1,22 @@ +{ + "sectionSubTitle": "Nuestro Blog", + "sectionTitle": "Últimas Noticias y Comunicados", + "knowMore": "Saber Más", + "posts": { + "new-tps-designations-what-you-need-to-know": { + "title": "Nuevas Designaciones de TPS: Lo Que Necesitas Saber", + "summary": "Cambios recientes en la política afectan a miles de inmigrantes. Descubre cómo las actualizaciones de TPS pueden impactar tu caso y qué acciones tomar.", + "description": "

Los cambios recientes en la política afectan a miles de inmigrantes. Aprende cómo las actualizaciones del Estatus de Protección Temporal (TPS) pueden impactar tu caso y qué pasos debes seguir...

... contenido completo aquí ..." + }, + "h1b-season-2025-preparation-strategies": { + "title": "Temporada H-1B 2025: Estrategias de Preparación", + "summary": "Se acerca la lotería anual de visas H-1B. Nuestra guía integral ayuda a empleadores y trabajadores a navegar el proceso y mejorar sus posibilidades.", + "description": "

El período de registro para la visa H-1B del año fiscal 2026 se cerró recientemente...

... contenido completo aquí ..." + }, + "family-immigration-backlogs-alternative-options": { + "title": "Retrasos en la Inmigración Familiar: Opciones Alternativas", + "summary": "Mientras las categorías de preferencia familiar enfrentan demoras, descubre vías alternativas para reunirte con tus seres queridos.", + "description": "

Mientras las categorías de inmigración familiar enfrentan retrasos significativos...

... contenido completo aquí ..." + } + } +} \ No newline at end of file diff --git a/utils/constant.utils.js b/utils/constant.utils.js index b4ddb25..3e5d5b7 100644 --- a/utils/constant.utils.js +++ b/utils/constant.utils.js @@ -30,6 +30,18 @@ import iconImg1 from '/public/images/home/icons/strategic-planning.webp' import iconImg2 from '/public/images/home/icons/expert-preparation.webp' import iconImg3 from '/public/images/home/icons/ongoing-support.webp' +import blogImg1 from "/public/images/blog/blog-1.webp"; +import blogImg2 from "/public/images/blog/blog-2.webp"; +import blogImg3 from "/public/images/blog/blog-3.webp"; + +import blogSingleImg1 from "/public/images/blog/blog-detail-1.webp"; +import blogSingleImg2 from "/public/images/blog/blog-detail-2.webp"; +import blogSingleImg3 from "/public/images/blog/blog-detail-3.webp"; + +import bannerImg1 from "/public/images/blog/banner-1.webp"; +import bannerImg2 from "/public/images/blog/banner-2.webp"; +import bannerImg3 from "/public/images/blog/banner-3.webp"; + export const featuresData = [ { img: iconImg1, @@ -205,3 +217,43 @@ export const MissionVision = [ }, ] +const blog = [ + { + id: '1', + slug: 'new-tps-designations-what-you-need-to-know', + bannerImg: bannerImg1, + screens: blogImg1, + blogSingleImg: blogSingleImg1, + author: 'Anne William', + authorTitle: 'Admin', + create_at: '25 Sep 2022', + comment: '35', + blClass: 'format-standard-image' + }, + { + id: '2', + slug: 'h1b-season-2025-preparation-strategies', + bannerImg: bannerImg2, + screens: blogImg2, + blogSingleImg: blogSingleImg2, + author: 'Robert Fox', + authorTitle: 'Admin', + create_at: '12 Jun 2023', + comment: '80', + blClass: 'format-standard-image' + }, + { + id: '3', + slug: 'family-immigration-backlogs-alternative-options', + bannerImg: bannerImg3, + screens: blogImg3, + blogSingleImg: blogSingleImg3, + author: 'Devon Lane', + authorTitle: 'Admin', + create_at: '03 Dec 2024', + comment: '95', + blClass: 'format-video' + } +]; + +export default blog; From cbb549caa5262cae9d2c99e5cba86f217538c583 Mon Sep 17 00:00:00 2001 From: selvi Date: Mon, 18 Aug 2025 19:37:51 +0530 Subject: [PATCH 2/3] contact language updated --- components/ContactFrom/ContactForm.js | 65 +++++++++++++++++++-------- components/Contactpage/Contactpage.js | 33 +++++++------- next-i18next.config.js | 14 +++--- pages/contact/index.js | 2 +- public/locales/en/contact.json | 35 +++++++++++++++ public/locales/es/contact.json | 35 +++++++++++++++ 6 files changed, 141 insertions(+), 43 deletions(-) create mode 100644 public/locales/en/contact.json create mode 100644 public/locales/es/contact.json diff --git a/components/ContactFrom/ContactForm.js b/components/ContactFrom/ContactForm.js index 2597810..b57485e 100644 --- a/components/ContactFrom/ContactForm.js +++ b/components/ContactFrom/ContactForm.js @@ -3,8 +3,11 @@ import React, { useState, useRef } from "react"; import SimpleReactValidator from "simple-react-validator"; import ReCAPTCHA from "react-google-recaptcha"; import axios from "axios"; +import { useTranslation } from 'next-i18next'; const ContactForm = () => { + const { t } = useTranslation("contact"); + const subjectOptions = t("form.subjectOptions", { returnObjects: true }); const [forms, setForms] = useState({ name: "", email: "", @@ -64,7 +67,7 @@ const ContactForm = () => { { headers: { "Content-Type": "application/json" } } ); - alert(response?.data?.message || "Message sent successfully!"); + alert(t("form.successMessage")); setForms({ name: "", @@ -84,7 +87,7 @@ const ContactForm = () => { } setRecaptchaToken(null); } catch (err) { - alert("Failed to send message. Please try again later."); + alert(t("form.failedMessage")); } } else { validator.showMessages(); @@ -103,9 +106,14 @@ const ContactForm = () => { name="name" onBlur={changeHandler} onChange={changeHandler} - placeholder="Your Name" + placeholder={t("form.namePlaceholder")} /> - {validator.message("name", forms.name, "required|alpha_space")} + {validator.message( + "name", + forms.name, + "required|alpha_space", + { messages: { required: t("form.requiredMessages.name") } } + )}
@@ -117,9 +125,14 @@ const ContactForm = () => { name="email" onBlur={changeHandler} onChange={changeHandler} - placeholder="Your Email" + placeholder={t("form.emailPlaceholder")} /> - {validator.message("email", forms.email, "required|email")} + {validator.message( + "email", + forms.email, + "required|email", + { messages: { required: t("form.requiredMessages.email") } } + )}
@@ -131,9 +144,14 @@ const ContactForm = () => { name="phone" onBlur={changeHandler} onChange={changeHandler} - placeholder="Your phone" + placeholder={t("form.phonePlaceholder")} /> - {validator.message("phone", forms.phone, "required|phone")} + {validator.message( + "phone", + forms.phone, + "required|phone", + { messages: { required: t("form.requiredMessages.phone") } } + )}
@@ -145,26 +163,37 @@ const ContactForm = () => { value={forms.subject} name="subject" > - - - - - - + + {Array.isArray(subjectOptions) && + subjectOptions.map((opt, idx) => ( + + ))} - {validator.message("subject", forms.subject, "required")} + + {validator.message( + "subject", + forms.subject, + "required", + { messages: { required: t("form.requiredMessages.subject") } } + )} +
- {validator.message("message", forms.message, "required")} + {validator.message( + "message", + forms.message, + "required", + { messages: { required: t("form.requiredMessages.message") } } + )}
@@ -178,7 +207,7 @@ const ContactForm = () => {
diff --git a/components/Contactpage/Contactpage.js b/components/Contactpage/Contactpage.js index 1c5f4af..59ee799 100644 --- a/components/Contactpage/Contactpage.js +++ b/components/Contactpage/Contactpage.js @@ -1,10 +1,11 @@ import React from 'react'; import ContactForm from '../ContactFrom/ContactForm' +import { useTranslation } from 'next-i18next'; const Contactpage = () => { - - return( + const { t } = useTranslation("contact"); + return (
@@ -32,12 +33,11 @@ const Contactpage = () => {
-

Email Us

-

info@janahanlaw.com

- {/*

helloyou@gmail.com

*/} +

{t("contactInfo.emailTitle")}

+

{t("contactInfo.email")}

- +
@@ -46,32 +46,31 @@ const Contactpage = () => {
-

Call Now

-

+1 (305) 330-7413

- {/*

+1 800 123 654 987

*/} +

{t("contactInfo.callTitle")}

+

{t("contactInfo.phone")}

- +
-

Have Any Question?

-

We’re here to help with all your U.S. immigration and legal needs — contact Janahan Law for trusted guidance today.

+

{t('contactInfo.questionTitle')}

+

{t('contactInfo.questionDesc')}

- +
- + - + {/*
*/}
- ) - + ) + } export default Contactpage; diff --git a/next-i18next.config.js b/next-i18next.config.js index 2eb1d60..64c0762 100644 --- a/next-i18next.config.js +++ b/next-i18next.config.js @@ -1,4 +1,4 @@ -const { default: OurApproach } = require("./pages/our-approach"); +// const { default: OurApproach } = require("./pages/our-approach"); module.exports = { i18n: { @@ -6,18 +6,18 @@ module.exports = { locales: ['en', 'es'], localeDetection: false, }, - ns: ['common', 'menu', 'homeHero', 'home4Card'], + ns: ['common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction', 'ourMission', 'racialJustice', 'contact', 'ourApproach', 'ourStory', 'aboutService', 'aboutMission', 'aboutRacial', 'aboutDonor' ], defaultNS: 'common', // localePath: './public/locales', }; -// aakash - 'ourMission', 'racialJustice' +// aakash - ourMission, racialJustice -// Selvi - 'ourStory', 'aboutService', 'aboutMission', 'aboutRacial', 'aboutDonor' +// Selvi - 'ourStory', 'aboutService', 'aboutMission', 'aboutRacial', 'aboutDonor' -// Vidhya - OurApproach - -// Alagu Raj - 'common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction' +// Vidhya +// OurApproach +// Alagu Raj - 'common', 'menu', 'homeHero', 'home4Card', '(home)/homeAbout', '(home)/homeFeature', '(home)/testimonial', '(home)/homeCalltoAction' \ No newline at end of file diff --git a/pages/contact/index.js b/pages/contact/index.js index c0e970d..a5371e5 100644 --- a/pages/contact/index.js +++ b/pages/contact/index.js @@ -24,7 +24,7 @@ export default ContactPage; export async function getStaticProps({ locale }) { return { props: { - ...(await serverSideTranslations(locale, ['common', 'menu'])), // Add 'home', 'footer', etc. if needed + ...(await serverSideTranslations(locale, ['common', 'menu', 'contact'])), // Add 'home', 'footer', etc. if needed }, }; } diff --git a/public/locales/en/contact.json b/public/locales/en/contact.json new file mode 100644 index 0000000..ce08902 --- /dev/null +++ b/public/locales/en/contact.json @@ -0,0 +1,35 @@ +{ + "contactInfo": { + "emailTitle": "Email Us", + "email": "info@janahanlaw.com", + "callTitle": "Call Now", + "phone": "+1 (305) 330-7413", + "questionTitle": "Have Any Question?", + "questionDesc": "We’re here to help with all your U.S. immigration and legal needs — contact Janahan Law for trusted guidance today." + }, + "form": { + "namePlaceholder": "Your Name", + "emailPlaceholder": "Your Email", + "phonePlaceholder": "Your Phone", + "subjectPlaceholder": "Select Subject", + "subjectOptions": [ + "River Development", + "Village Development", + "Road Development", + "Town Development", + "Social Development" + ], + "messagePlaceholder": "Message", + "submitButton": "Submit Now", + "successMessage": "Message sent successfully!", + "failedMessage": "Failed to send message. Please try again later.", + "requiredMessages": { + "name": "Name is required", + "email": "Valid email is required", + "phone": "Phone number is required", + "subject": "Please select a subject", + "message": "Message is required", + "recaptcha": "Please complete the ReCAPTCHA" + } + } +} diff --git a/public/locales/es/contact.json b/public/locales/es/contact.json new file mode 100644 index 0000000..564bd7f --- /dev/null +++ b/public/locales/es/contact.json @@ -0,0 +1,35 @@ +{ + "contactInfo": { + "emailTitle": "Envíanos un correo", + "email": "info@janahanlaw.com", + "callTitle": "Llama ahora", + "phone": "+1 (305) 330-7413", + "questionTitle": "¿Tienes alguna pregunta?", + "questionDesc": "Estamos aquí para ayudarte con todas tus necesidades legales y de inmigración en EE. UU. — contacta a Janahan Law para obtener orientación confiable hoy." + }, + "form": { + "namePlaceholder": "Tu Nombre", + "emailPlaceholder": "Tu Correo Electrónico", + "phonePlaceholder": "Tu Teléfono", + "subjectPlaceholder": "Selecciona Asunto", + "subjectOptions": [ + "Desarrollo de Ríos", + "Desarrollo de Aldeas", + "Desarrollo de Carreteras", + "Desarrollo de Ciudades", + "Desarrollo Social" + ], + "messagePlaceholder": "Mensaje", + "submitButton": "Enviar Ahora", + "successMessage": "¡Mensaje enviado con éxito!", + "failedMessage": "Error al enviar el mensaje. Por favor, inténtalo de nuevo más tarde.", + "requiredMessages": { + "name": "El nombre es obligatorio", + "email": "Correo electrónico válido es obligatorio", + "phone": "El teléfono es obligatorio", + "subject": "Por favor selecciona un asunto", + "message": "El mensaje es obligatorio", + "recaptcha": "Por favor completa el ReCAPTCHA" + } + } +} From 28feb20726cca9167844979641a49883b1620d98 Mon Sep 17 00:00:00 2001 From: selvi Date: Mon, 18 Aug 2025 19:51:05 +0530 Subject: [PATCH 3/3] contact language updated --- next-i18next.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/next-i18next.config.js b/next-i18next.config.js index 413ac15..c469875 100644 --- a/next-i18next.config.js +++ b/next-i18next.config.js @@ -14,8 +14,8 @@ module.exports = { // aakash - ourMission, racialJustice -// Selvi - 'ourStory', 'aboutService', 'aboutMission', 'aboutRacial', 'aboutDonor' - +// Selvi - 'ourStory', 'aboutService', 'aboutMission', 'aboutRacial', 'aboutDonor', 'contact', + // Vidhya // OurApproach